package com.xbongbong.pro.service.toolbox.statistic.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.BelongEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.enums.StarEnum;
import com.xbongbong.paas.enums.UnitEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasCommentModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.pro.appdetail.pojo.MobileDetailDialPhonePojo;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.dictionary.pojo.DictionaryPojo;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.TimeTypeEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.StatisticsServicesErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ExportProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.service.toolbox.statistic.util.ChartResultUtil;
import com.xbongbong.pro.statistic.enums.IndicatorRuleEnum;
import com.xbongbong.pro.statistic.enums.ResultFromEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.enums.ThroughParamEnum;
import com.xbongbong.pro.statistic.pojo.FiscalYearTimePojo;
import com.xbongbong.pro.statistic.pojo.TimePojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultBasePojo;
import com.xbongbong.pro.statistic.result.pojo.TitlePojo;
import com.xbongbong.pro.statistic.result.pojo.vo.ResultDataTableVO;
import com.xbongbong.pro.statistic.through.pojo.ResultThroughPojo;
import com.xbongbong.pro.statistic.through.pojo.TableDataInfoPojo;
import com.xbongbong.pro.statistic.through.pojo.dto.ResultThroughDTO;
import com.xbongbong.pro.statistic.through.pojo.dto.ThroughDTO;
import com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO;
import com.xbongbong.pro.weblist.pojo.CustomerCommunicatePojo;
import com.xbongbong.pro.weblist.pojo.vo.CommunicateVO;
import com.xbongbong.pro.workorder.pojo.TimeConsumingOutPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.constant.PageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ClueUserEntity;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.CustomerStageEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.FormDataDictionaryEntity;
import com.xbongbong.saas.domain.entity.OpportunityUserEntity;
import com.xbongbong.saas.domain.entity.PayPlanUserEntity;
import com.xbongbong.saas.domain.entity.PaymentTaskUserEntity;
import com.xbongbong.saas.domain.entity.PaymentUserEntity;
import com.xbongbong.saas.domain.entity.ProductionOrderUserEntity;
import com.xbongbong.saas.domain.entity.TagLinkEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.enums.BusinessCommentEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.SpecialSymbolEnum;
import com.xbongbong.saas.enums.WorkOrderForStatisticsEnum;
import com.xbongbong.saas.enums.WorkOrderStatusEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.CommunicateBaseEnum;
import com.xbongbong.saas.enums.business.BadDebtEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.enums.business.OtherIncomeEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PayRelationshipEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentRelationshipEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.dictionary.ClueStatusEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.OrderStatusEnum;
import com.xbongbong.saas.enums.dictionary.PayPlanStatusEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.dictionary.PaymentTaskStatusEnum;
import com.xbongbong.saas.enums.dictionary.ProductionOrderStatusEnum;
import com.xbongbong.saas.enums.dictionary.RefundReasonEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.subform.ContractProductSubFormEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.model.CustomerStageLogModel;
import com.xbongbong.saas.model.CustomerStageModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.FormDataDictionaryModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LikeModel;
import com.xbongbong.saas.model.SaleStageModel;
import com.xbongbong.saas.model.SpecificationModel;
import com.xbongbong.saas.model.TagLinkModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getJsonArrOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author zcp
 * @version v1.0
 * @date 2019/4/18 19:23
 * @since v1.0
 */
@Component
public class ThroughHelp implements ThroughProService {
    private static final Logger LOG = LoggerFactory.getLogger(ThroughHelp.class);
    @Resource
    private ChartQueryHelp chartQueryHelp;
    @Resource
    private FormHelp formHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private TagLinkModel tagLinkModel;
    @Resource
    private PushModel pushModel;
    @Resource
    private PaasCommentModel paasCommentModel;
    @Resource
    private LikeModel likeModel;
    @Resource
    private SpecificationModel specificationModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private SaleStageModel saleStageModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private TransferSubFormHelper transferSubFormHelper;
    @Resource
    private CustomerStageLogModel customerStageLogModel;
    @Resource
    private UserModel userModel;
    @Resource
    private CustomerStageModel customerStageModel;
    @Resource
    private ChartRuleQueryHelp chartRuleQueryHelp;
    @Resource
    private FormDataDictionaryModel formDataDictionaryModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;

    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(BasicConstant.ZERO);
    }

    /**
     * 处理穿透后的时间相关参数
    * @param splitFlag 是否切分flag（如筛选年时要切分成月、筛选月要展示成日的，则需要在穿透时处理timeType）
     * @param fiscalYearTimePojo 统计时间参数pojo
     * @param startTime 穿透开始时间
     * @param endTime 穿透结束时间
     * @return com.xbongbong.pro.statistic.pojo.TimePojo
     * @author zcp
     * @date 2019/4/18 22:00
     * @since v1.0
     * @version v1.0
     */
    @Override
    public TimePojo formatThroughTimeInfo(boolean splitFlag, FiscalYearTimePojo fiscalYearTimePojo, Integer startTime, Integer endTime){
        TimePojo timePojo = new TimePojo();
        timePojo.setStartTime(startTime);
        timePojo.setEndTime(endTime);
        timePojo.setTimeType(fiscalYearTimePojo.getTimeType4DefaultMonth());
        if (splitFlag) {
            //如果需要分割（如筛选年时要切分成月、筛选月要展示成日的，则需要在穿透时处理timeType）
            TimeTypeEnum timeTypeEnum = fiscalYearTimePojo.getTimeTypeEnum4DefaultMonth();
            switch (timeTypeEnum) {
                //筛选年、半年、季度时，展示月
                case YEAR:
                case YEAR_HALF_UP:
                case YEAR_HALF_DOWN:
                case SEASON:
                    timePojo.setTimeType(TimeTypeEnum.MONTH.getCode());
                    break;
                //筛选月份，展示日
                case MONTH:
                case MONTH_LAST:
                case WEEK:
                case WEEK_LAST:
                    timePojo.setTimeType(TimeTypeEnum.DAY.getCode());
                    break;
                default:
                    timePojo.setTimeType(fiscalYearTimePojo.getTimeType4DefaultMonth());
                    break;
            }
        }
        return timePojo;
    }

    /**
     * 封装表格数据，并处理穿透参数（如果不需要穿透，则不用处理）
     * 不需要穿透，则直接new ResultDataTableVO(value, null)即可
     * @param value 显示内容
     * @param throughDTO 穿透基础参数dto
     * @param timePojo 穿透时间参数pojo
     * @return com.xbongbong.pro.statistic.result.pojo.vo.ResultDataTableVO
     * @author zcp
     * @date 2019/4/19 10:34
     * @since v1.0
     * @version v1.0
     */
    @Override
    public ResultDataTableVO formatResultDataTableVO(String value, ThroughDTO throughDTO, TimePojo timePojo) {
        String through = getThrough(throughDTO, timePojo);
        return new ResultDataTableVO(value, through);
    }


    @Override
    public String getThrough(ThroughDTO throughDto, TimePojo timePojo) {
        return getThrough(throughDto, timePojo, null);
    }
    /**
     * 得到穿透参数
     * @param throughDto 穿透基础参数dto
     * @param timePojo 穿透时间参数pojo
     * @param sourcePage 穿透来源页
     * @return java.lang.String
     * @author zcp
     * @date 2019/4/24 14:56
     * @since v1.0
     * @version v1.0
     */
    @Override
    public String getThrough(ThroughDTO throughDto, TimePojo timePojo, String sourcePage) {
        if (throughDto == null) {
            //不需要穿透
            return null;
        }
        JSONObject throughObject = new JSONObject();
        SystemCodeEnum systemCodeEnum = throughDto.getSystemCodeEnum();
        JSONObject baseThrough = throughDto.getBaseThrough();
        if (baseThrough != null) {
            throughObject.putAll(baseThrough);
        }
        if (systemCodeEnum != null) {
            //穿透系统指标类型
            throughObject.put(ThroughParamEnum.SYSTEM_CODE.getKey(), systemCodeEnum.getSystemCode());
        }
        //穿透的时间类型
        throughObject.put(ThroughParamEnum.TIME_TYPE.getKey(), timePojo.getTimeType());
        //穿透的开始时间戳
        throughObject.put(ThroughParamEnum.START_TIME.getKey(), timePojo.getStartTime());
        //穿透的结束时间戳
        throughObject.put(ThroughParamEnum.END_TIME.getKey(), timePojo.getEndTime());
        if (Objects.nonNull(sourcePage)) {
            throughObject.put(ThroughParamEnum.SOURCE_PAGE.getKey(), sourcePage);
        }
        return throughObject.toString();
    }

    /**
     * 判断是否时移动端产品销量，如果是，则不穿透
     * @param chartResultBasePojo 参数pojo
     * @param systemCodeEnum 系统指标枚举
     * @return boolean true 可以穿透，false不可以穿透
     * @author zcp
     * @date 2019/5/20 17:40
     * @since v1.0
     * @version v1.0
     */
    @Override
    public boolean checkThrough(ChartResultBasePojo chartResultBasePojo, SystemCodeEnum systemCodeEnum) {
        //置入穿透员工
        String platform = chartResultBasePojo.getPlatform();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(chartResultBasePojo.getChartEntity().getDriverSources().getInteger("businessType"));
        //移动端产品销量不穿透
        boolean flag = XbbRefTypeEnum.CUSTOMER_COMMUNICATE == xbbRefTypeEnum || XbbRefTypeEnum.COST_ADJUST == xbbRefTypeEnum || XbbRefTypeEnum.COMMUNICATE_PLAN == xbbRefTypeEnum || (PlatFormEnum.DINGTALK.getValue().equals(platform) && (SystemCodeEnum.PERFORMANCE_PRODUCT_SALES == systemCodeEnum
                || SystemCodeEnum.PK_PRODUCT_SALES == systemCodeEnum
                || SystemCodeEnum.PRODUCT_SALES_CHART == systemCodeEnum));
        //true 可以穿透，false不可以穿透
        return !flag;
    }

    /**
     * 获取穿透结果list
     * @param resultFromEnum 统计请求来源枚举
     * @param systemCodeEnum 系统指标枚举
     * @param resultThroughPojo 穿透参数pojo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException error
     * @author zcp
     * @date 2019/4/30 11:18
     * @since v1.0
     * @version v1.0
     */
    @Override
    public ResultThroughVO getThroughList(ResultFromEnum resultFromEnum, SystemCodeEnum systemCodeEnum, ResultThroughPojo resultThroughPojo, ResultThroughDTO resultThroughDTO) throws XbbException {
        String corpid = resultThroughPojo.getCorpid();
        Boolean exportFlag = resultThroughDTO.getExportFlag();
        //处理分页：需先处理分页基础参数，防止为空
        ChartResultUtil.formatPage(resultThroughPojo, PageConstant.DEFAULT_PAGE_SIZE_SMALL);
        Integer page = resultThroughPojo.getPage();
        Integer pageSize = resultThroughPojo.getPageSize();
        ResultThroughVO resultThroughVo = new ResultThroughVO();
        //得到穿透后的查询条件
        BoolQueryBuilder boolQueryBuilder;
        //设置索引、排序等
        IndexTypeEnum indexTypeEnum = null;
        List<SortBuilder> sortBuilderList = null;
        XbbRefTypeEnum xbbRefTypeEnum = systemCodeEnum.getXbbRefTypeEnum();
        IndicatorRuleEnum indicatorRuleEnum = systemCodeEnum.getIndicatorRuleEnum();
        // 排序字段设置
        Map<String, String> sortMap = resultThroughDTO.getSortMap();
        String sortField = null;
        SortOrder order = SortOrder.DESC;
        Boolean flag = false;
        if (sortMap!=null && !sortMap.isEmpty()){
            sortField = sortMap.get("field");
            String sort = sortMap.get("sort");
            if (StringUtil.isNotEmpty(sortField) && StringUtil.isNotEmpty(sort)) {
                flag = true;
            }
            if(SortOrder.ASC.toString().equals(sort)){
                order = SortOrder.ASC;
            }
            String raw = ".raw";
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(resultThroughDTO.getFiledType());
            if(FieldTypeEnum.TEXT.getEsalias().equals( fieldTypeEnum.getEsalias())){
                sortField = sortField + raw;
            }
            //预收款余额列表都不要加data.
            if(!Objects.equals(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(),xbbRefTypeEnum.getCode()) && !Objects.equals(XbbRefTypeEnum.PREPAY_BALANCE.getCode(),xbbRefTypeEnum.getCode())){
                //系统字段不用加data.
                if (!BelongEnum.SYSTEM.getAlias().equals(fieldTypeEnum.getBelong())) {
                    sortField = "data." + sortField;
                } else if (Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.SERIALNO.getType()) && !sortField.contains(fieldTypeEnum.getAlias())) {
                    sortField = "data." + sortField;
                }
            }
            if(SortOrder.ASC.toString().equals(sortMap.get("sort"))){
                order = SortOrder.ASC;
            }
        }

        //合同业绩分配是否开启
        boolean openRule = false;
        Class clazz = PaasFormDataEntityExt.class;
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                indexTypeEnum =  indexTypeModel.getCustomerIndex(resultThroughPojo.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));

                ChartEntity chartEntity = resultThroughPojo.getChartEntity();
                if(Objects.nonNull(chartEntity) && Objects.nonNull(chartEntity.getTimeAttr())){
                    String timeAttr = chartEntity.getTimeAttr().getString("attr");
                    if(CustomerManagementEnum.ADD_TIME.getAttr().equals(timeAttr)){
                        sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                    } else if(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr().equals(timeAttr)){
                        sortBuilderList = Collections.singletonList(new FieldSortBuilder(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.LAST_CONNECT_TIME)).order(SortOrder.DESC));
                    }
                }
                boolQueryBuilder = chartQueryHelp.throughQuery4Customer(systemCodeEnum, resultThroughPojo, resultThroughVo);
                // chartRuleQueryHelp.formOpenBase(boolQueryBuilder, resultThroughPojo, XbbRefTypeEnum.CUSTOMER_MANAGEMENT);
                break;
            case CUSTOMER_COMMUNICATE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(CustomerCommunicateEnum.getAttrConnectData(CustomerCommunicateEnum.COMMUNICATE_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Communicate(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case SALES_OPPORTUNITY:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OPPORTUNITY;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(SalesOpportunityEnum.getAttrConnectData(SalesOpportunityEnum.ESTIMATE_END_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Opportunity(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case CONTRACT:
                if (IndicatorRuleEnum.RED_CONTRACT == indicatorRuleEnum) {
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_REFUND;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(RefundEnum.getAttrConnectData(RefundEnum.SIGN_DATE)).order(SortOrder.DESC));
                } else {
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(ContractEnum.getAttrConnectData(ContractEnum.SIGN_TIME)).order(SortOrder.DESC));
                }
                //合同业绩分配是否开启
                openRule = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias(),"1");
                boolQueryBuilder = chartQueryHelp.throughQuery4Contract(openRule, systemCodeEnum, resultThroughPojo, resultThroughVo);
                // chartRuleQueryHelp.formOpenBase(boolQueryBuilder, resultThroughPojo, XbbRefTypeEnum.CONTRACT);
                break;
            case ORDER:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(ContractEnum.getAttrConnectData(ContractEnum.SIGN_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Contract(false, systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case RETURN:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_REFUND;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(RefundEnum.getAttrConnectData(RefundEnum.SIGN_DATE)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Contract(false, systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case PAYMENT:
                if (IndicatorRuleEnum.PAYMENT_UN == indicatorRuleEnum || IndicatorRuleEnum.PAYMENT_TASK == indicatorRuleEnum) {
                    //已收款展示回款单，应收未收展示应收款
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(PaymentEnum.getAttrConnectData(PaymentEnum.ESTIMATE_TIME)).order(SortOrder.DESC));
                } else {
                    if (resultThroughDTO.getAccountId() != null) {
                        List<Long> accountIds = fundHelp.dealWithFundAccount(resultThroughDTO.getAccountId(), corpid);
                        resultThroughPojo.setAccountIdList(accountIds);
                    }
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(PaymentSheetEnum.getAttrConnectData(PaymentSheetEnum.PAYMENT_TIME)).order(SortOrder.DESC));
                }
                //合同业绩分配是否开启
                openRule = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias(),"1");
                boolQueryBuilder = chartQueryHelp.throughQuery4Payment(resultFromEnum, openRule, systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case CONTACT:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTACT;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Contact(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case INVOICE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_INVOICE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(InvoiceEnum.getAttrConnectData(InvoiceEnum.INVOICE_DATE)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Invoice(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case PURCHASE_INVOICE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_PURCHASE_INVOICE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(PurchaseInvoiceEnum.getAttrConnectData(PurchaseInvoiceEnum.INVOICE_DATE)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4InvoicePurchase(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case PRODUCT:
                //目前只有合同产品穿透、展示合同产品list
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT_PRODUCT;
                boolQueryBuilder = chartQueryHelp.throughQuery4Product(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case REFUND:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_REFUND;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(RefundEnum.getAttrConnectData(RefundEnum.SIGN_DATE)).order(SortOrder.DESC));
                //此处不用获取业绩分配开关（红冲合同<归属到了合同模块>是在合同内直接调用的红冲合同查询）
                boolQueryBuilder = chartQueryHelp.throughQuery4Refund(openRule, systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case PAY_PLAN:
                if (IndicatorRuleEnum.PAY_UN == indicatorRuleEnum) {
                    //已付款展示回款单，未付款展示付款计划（移动端没有付款单列表）
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAY_PLAN;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(PayPlanEnum.getAttrConnectData(PayPlanEnum.ESTIMATE_TIME)).order(SortOrder.DESC));
                    boolQueryBuilder = chartQueryHelp.throughQuery4Pay(systemCodeEnum, resultThroughPojo, resultThroughVo);
                } else {
                    if (resultThroughDTO.getAccountId() != null) {
                        List<Long> accountIds = fundHelp.dealWithFundAccount(resultThroughDTO.getAccountId(), corpid);
                        resultThroughPojo.setAccountIdList(accountIds);
                    }
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET;
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(PaySheetEnum.getAttrConnectData(PaySheetEnum.REAL_PAY_TIME)).order(SortOrder.DESC));
                    boolQueryBuilder = chartQueryHelp.throughQuery4PaySheet(systemCodeEnum, resultThroughPojo, resultThroughVo);
                }
                break;
            case PURCHASE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_PURCHASE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(PurchaseEnum.getAttrConnectData(PurchaseEnum.SIGN_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Purchase(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case PRODUCTION_ORDER:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER;
                if (IndicatorRuleEnum.PRODUCTION_ORDER_ADD == indicatorRuleEnum) {
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                } else {
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder(ProductionOrderEnum.getAttrConnectData(ProductionOrderEnum.COMPLETE_TIME)).order(SortOrder.DESC));
                }
                boolQueryBuilder = chartQueryHelp.throughQuery4ProductionOrder(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case WORK_ORDER:
                clazz = WorkOrderEntity.class;
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_WORK_ORDER;
                if (IndicatorRuleEnum.WORK_ORDER_CLOSE == indicatorRuleEnum) {
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder("closeTime").order(SortOrder.DESC));
                } else if (IndicatorRuleEnum.WORK_ORDER_FINISH == indicatorRuleEnum || IndicatorRuleEnum.WORK_ORDER_FINISH_DELAY == indicatorRuleEnum || IndicatorRuleEnum.WORK_ORDER_FINISH_INTIME == indicatorRuleEnum) {
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder("endTime").order(SortOrder.DESC));
                } else {
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                }
                boolQueryBuilder = chartQueryHelp.throughQuery4WorkOrder(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case QUOTATION:
                if (IndicatorRuleEnum.QUOTATION_CUSTOMER_COUNT == indicatorRuleEnum) {
                    indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                    sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                } else {
                    indexTypeEnum = IndexTypeEnum.IDX_SAAS_QUOTATION;
                    sortBuilderList = Arrays.asList(new FieldSortBuilder(QuotationEnum.getAttrConnectData(QuotationEnum.QUOTATION_TIME)).order(SortOrder.DESC),
                            new FieldSortBuilder("addTime").order(SortOrder.DESC));
                }
                boolQueryBuilder = chartQueryHelp.throughQuery4Quotation(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case CLUE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CLUE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4Clue(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case MARKET_ACTIVITY:
                indexTypeEnum = IndexTypeEnum.IDX_STATICS_MARKET_DATA;
                // 市场活动比较特殊,它里边会支持跳转到多个表单 只能是这么个笨办法了,我也没有其他办法
                boolQueryBuilder=chartQueryHelp.throughQuery4Market(systemCodeEnum, resultThroughPojo, resultThroughVo, indexTypeEnum);
                boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
                // 骚逻辑
                sortBuilderList = Collections.singletonList(new FieldSortBuilder("addTime").order(SortOrder.DESC));
                indexTypeEnum = getIndexType2Market(resultThroughPojo);
                systemCodeEnum = getSystemCode2Market(resultThroughPojo);
                break;
            case OTHER_INCOME:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OTHER_INCOME;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(OtherIncomeEnum.getAttrConnectData(OtherIncomeEnum.INCOME_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4OtherIncome(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            case OTHER_EXPENSE:
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OTHER_EXPENSE;
                sortBuilderList = Collections.singletonList(new FieldSortBuilder(OtherExpenseEnum.getAttrConnectData(OtherExpenseEnum.EXPENSE_TIME)).order(SortOrder.DESC));
                boolQueryBuilder = chartQueryHelp.throughQuery4OtherExpense(systemCodeEnum, resultThroughPojo, resultThroughVo);
                break;
            default:
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224066);
        }
        if (flag){
            sortBuilderList = Collections.singletonList(new FieldSortBuilder(sortField).order(order));
        }
        List list = new ArrayList<>();
        if(exportFlag != null && exportFlag){
            //最多导出5w条
            list = esHelper.findByScroll4Export(indexTypeEnum, boolQueryBuilder, clazz, null, sortBuilderList);
        }else{
            //分页查询
            XbbAggregatedPage esEntities = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, clazz, null, page, pageSize, sortBuilderList);
            int rowCounts = 0;
            if (esEntities != null) {
                rowCounts = (int) esEntities.getTotalElements();
                list = esEntities.getContent();
            }
            //封装web端结果
            PageHelper pageHelper = PageHelperUtil.initPageHelper(rowCounts, page, pageSize, PageConstant.DEFAULT_PAGE_SIZE);
            resultThroughVo.setPageHelper(pageHelper);
        }

        resultThroughVo = formatList(resultFromEnum, resultThroughPojo, openRule, systemCodeEnum, list, resultThroughVo, resultThroughDTO);
        // 判断是否有导出权限
        determineImportPermission(resultThroughVo, systemCodeEnum, resultThroughDTO);
        return resultThroughVo;
    }
    /**
     * 判断穿透过去的数据是否支持导出
     * @param resultThroughVo
     * @param systemCodeEnum
     */
    public void determineImportPermission(ResultThroughVO resultThroughVo, SystemCodeEnum systemCodeEnum, ResultThroughDTO resultThroughDTO) {
        resultThroughVo.setShowExport(BasicConstant.ONE);
        XbbRefTypeEnum xbbRefTypeEnum = systemCodeEnum.getXbbRefTypeEnum();
        ExportProPermissionAliasEnum exportProPermissionAliasEnum = ExportProPermissionAliasEnum.getByCode(xbbRefTypeEnum.getCode());
        if (Objects.nonNull(exportProPermissionAliasEnum)) {
            Set<String> permSet = resultThroughDTO.getLoginUser().getPermSet();
            String alias = exportProPermissionAliasEnum.getAlias();
            if (!permSet.contains(alias) && !Objects.equals(alias, StringConstant.POSITIVE_NUMBER)) {
                resultThroughVo.setShowExport(BasicConstant.ZERO);
            }
        }
    }

    private SystemCodeEnum getSystemCode2Market(ResultThroughPojo resultThroughPojo) throws XbbException {
        String dictionaryCode = resultThroughPojo.getDictionaryCode();
        String[] split = dictionaryCode.split("\\+");
        SystemCodeEnum systemCodeEnum;
        switch (split[1]){
            case "clueNum":
                systemCodeEnum = SystemCodeEnum.CLUE_TOTAL_BOARD;
                break;
            case "clueInvalid":
            case "conversionClue":
                systemCodeEnum = SystemCodeEnum.CLUE_TOTAL_BOARD;
                break;
            case "customer":
                systemCodeEnum = SystemCodeEnum.CUSTOMER_TOTAL_CHART;
                break;
            case "opportunityTotal":
                systemCodeEnum = SystemCodeEnum.OPPORTUNITY_ADD_CHART;
                break;
            case "opportunityWin":
                systemCodeEnum =  SystemCodeEnum.OPPORTUNITY_ADD_CHART;
                break;
            case "contract":
                // TODO: 2022/3/8  这个不清楚有啥用
                systemCodeEnum = SystemCodeEnum.CONTRACT_TABLE_CHART;
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        return systemCodeEnum;
    }

    private IndexTypeEnum getIndexType2Market(ResultThroughPojo resultThroughPojo) throws XbbException {
        String dictionaryCode = resultThroughPojo.getDictionaryCode();
        String[] split = dictionaryCode.split("\\+");
        IndexTypeEnum indexTypeEnum;
        switch (split[1]){
            case "clueNum":
               indexTypeEnum = IndexTypeEnum.IDX_SAAS_CLUE;
                break;
            case "clueInvalid":
            case "conversionClue":
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CLUE;
                break;
            case "customer":
                indexTypeEnum = indexTypeModel.getCustomerIndex(resultThroughPojo.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                break;
            case "opportunityTotal":
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OPPORTUNITY;
                break;
            case "opportunityWin":
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_OPPORTUNITY;
                break;
            case "contract":
                indexTypeEnum = IndexTypeEnum.IDX_SAAS_CONTRACT;
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        return indexTypeEnum;

    }

    //-----------------------------------------以下为private方法-----------------------------------------
    /**
     * 格式化list，转换为穿透后的标题和数据，塞入resultThroughVo内
     * @param resultFromEnum 统计请求来源枚举
     * @param resultThroughPojo 穿透参数pojo
     * @param openRule 合同业绩分配是否开启
     * @param systemCodeEnum 系统指标枚举
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/4/30 20:32
     * @since v1.0
     * @version v1.0
     */
    @Override
    public ResultThroughVO formatList(ResultFromEnum resultFromEnum, ResultThroughPojo resultThroughPojo, boolean openRule, SystemCodeEnum systemCodeEnum, List list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        String corpid = resultThroughPojo.getCorpid();
        XbbRefTypeEnum xbbRefTypeEnum = systemCodeEnum.getXbbRefTypeEnum();
        IndicatorRuleEnum indicatorRuleEnum = systemCodeEnum.getIndicatorRuleEnum();
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                // 数据源是否来自客户阶段漏斗并且是流失穿透
                boolean customerFunnelChart = false;
                String code = resultThroughDTO.getDictionaryCode();
                if (StringUtil.isNotEmpty(code)) {
                    // 【传个formId过来，通过formId和stageCode获取阶段实体，判断阶段类型是否为失败阶段】
                    Long formId = resultThroughDTO.getRefId();
                    if (Objects.nonNull(formId) && formId > 0) {
                        CustomerStageEntity customerStage = customerStageModel.getByCode(corpid, formId, code);
                         customerFunnelChart = Objects.equals(systemCodeEnum, SystemCodeEnum.CUSTOMER_FUNNEL_CHART) && Objects.equals(StageTypeEnum.FAIL_STAGE.getType(), customerStage.getType());
                    }
                }
                boolean customerLoseReasonChart = Objects.equals(systemCodeEnum, SystemCodeEnum.CUSTOMER_LOSE_REASON_CHART);
                boolean customerBeforeStageChart = Objects.equals(systemCodeEnum, SystemCodeEnum.CUSTOMER_BEFORE_STAGE_CHART);
                //客户
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatCustomer4App(customerFunnelChart, customerLoseReasonChart, customerBeforeStageChart, corpid, list, resultThroughVo);
                } else {
                    return formatCustomer(customerFunnelChart, customerLoseReasonChart, customerBeforeStageChart, corpid, list, resultThroughVo);
                }
            case CUSTOMER_COMMUNICATE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatCommunicate4App(resultThroughPojo, list, resultThroughVo);
                } else {
                    return formatCommunicate(corpid, list, resultThroughVo);
                }
            case SALES_OPPORTUNITY:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatOpportunity4App(corpid, list, resultThroughVo);
                } else {
                    return formatOpportunity(corpid, list, resultThroughVo);
                }
            case CONTRACT:
                //内部判断是否为红冲合同，是则跳入退货退款展示
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatContract4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                } else {
                    return formatContract(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }
            case ORDER:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatOrder4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }else{
                    return formatOrder(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }
            case RETURN:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatReturn4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }else{
                    return formatReturn(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }
            case PAYMENT:
                if (ResultFromEnum.APP == resultFromEnum) {
                    if (IndicatorRuleEnum.PAYMENT_UN == indicatorRuleEnum || IndicatorRuleEnum.PAYMENT_TASK == indicatorRuleEnum) {
                        return formatPayment4App(corpid, list, resultThroughVo);
                    } else {
                        return formatPaymentSheet4App(corpid, list, resultThroughVo, openRule);
                    }
                } else {
                    //web端，已回款展示回款单、未收款展示应收款
                    if (IndicatorRuleEnum.PAYMENT_UN == indicatorRuleEnum || IndicatorRuleEnum.PAYMENT_TASK == indicatorRuleEnum) {
                        return formatPaymentUn(corpid, list, resultThroughVo);
                    } else {
                        return formatPayment(indicatorRuleEnum, corpid, openRule, list, resultThroughVo);
                    }
                }
            case CONTACT:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatContact4App(corpid, list, resultThroughVo);
                } else {
                    return formatContact(corpid, list, resultThroughVo);
                }
            case INVOICE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatInvoice4App(corpid, list, resultThroughVo);
                } else {
                    return formatInvoice(corpid, list, resultThroughVo);
                }
            case PURCHASE_INVOICE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatInvoicePurchase4App(corpid, list, resultThroughVo);
                } else {
                    return formatInvoicePurchase(corpid, list, resultThroughVo);
                }
            case PRODUCT:
                List<ContractProductEntity> productList = transferSubFormHelper.transferFormDataToContractProductList(list);
                if (IndicatorRuleEnum.ORDER_PRODUCT == indicatorRuleEnum){
                    if (ResultFromEnum.APP == resultFromEnum) {
                        return formatProductOrder4App(corpid, productList, resultThroughVo);
                    }
                    return formatProductOrder(corpid, productList, resultThroughVo);
                }else if (IndicatorRuleEnum.RETURN_PRODUCT == indicatorRuleEnum){
                    if (ResultFromEnum.APP == resultFromEnum) {
                        return formatProductReturn4App(corpid, productList, resultThroughVo);
                    }
                    return formatProductReturn(corpid, productList, resultThroughVo);
                }else{
                    return formatProductContract(corpid, productList, resultThroughVo);
                }
            case REFUND:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatRefund4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                } else {
                    return formatRefund(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
                }
            case PAY_PLAN:
                if (ResultFromEnum.APP == resultFromEnum) {
                    if (IndicatorRuleEnum.PAY_UN == indicatorRuleEnum) {
                        return formatPayPlan4App(corpid, list, resultThroughVo);
                    } else {
                        return formatPaySheet4App(corpid, list, resultThroughVo);
                    }
                } else {
                    //web端，已回款展示回款单、未收款展示付款计划
                    if (IndicatorRuleEnum.PAY_UN == indicatorRuleEnum) {
                        return formatPayPlanUn(corpid, list, resultThroughVo);
                    } else {
                        return formatPayPlan(indicatorRuleEnum, corpid, list, resultThroughVo);
                    }
                }
            case PURCHASE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatPurchase4App(corpid, list, resultThroughVo);
                } else {
                    return formatPurchase(corpid, list, resultThroughVo);
                }
            case PRODUCTION_ORDER:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatProductionOrder4App(corpid, list, resultThroughVo);
                } else {
                    return formatProductionOrder(corpid, list, resultThroughVo);
                }
            case WORK_ORDER:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatWorkOrder4App(corpid, list, resultThroughVo);
                } else {
                    return formatWorkOrder(indicatorRuleEnum, corpid, list, resultThroughVo);
                }
            case QUOTATION:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatQuotation4App(indicatorRuleEnum, corpid, list, resultThroughVo);
                } else {
                    return formatQuotation(indicatorRuleEnum, corpid, list, resultThroughVo);
                }
            case CLUE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return formatClue4App(corpid, list, resultThroughVo, resultThroughDTO);
                } else {
                    return formatClue(corpid, list, resultThroughVo, resultThroughDTO);
                }
            case OTHER_INCOME:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return  formatOtherIncome4App(corpid, list, resultThroughVo, resultThroughDTO);
                } else {
                    return formatOtherIncome(corpid, list, resultThroughVo, resultThroughDTO);
                }
            case OTHER_EXPENSE:
                if (ResultFromEnum.APP == resultFromEnum) {
                    return  formatOtherExpense4App(corpid, list, resultThroughVo, resultThroughDTO);
                } else {
                    return formatOtherExpense(corpid, list, resultThroughVo, resultThroughDTO);
                }
            default:
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224055);
        }
    }

    /**
     * 封装app其他支出单返回
     *
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @param resultThroughDTO
     * @return
     */
    private ResultThroughVO formatOtherExpense4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.OTHER_EXPENSE.getCode());
        Set<String> userIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(OtherExpenseEnum.BELONG_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //支付方式
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.OTHER_EXPENSE.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        Map<String, String> payMethodMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.OTHER_EXPENSE_PAY_METHOD, corpid, formId);
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<FormTitlePoJo> titleList = new ArrayList<>();
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            JSONObject data = entityExt.getData();
            //负责人
            String belongUser = userNameMap.getOrDefault(data.getString(OtherExpenseEnum.BELONG_ID.getAttr()), "");
            summaryList.add(commonHelp.setSummary(OtherExpenseEnum.BELONG_ID.getAttrName(), belongUser));
            //收款日期
            String timeStr = "";
            Long time = data.getLong(OtherExpenseEnum.EXPENSE_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            summaryList.add(commonHelp.setSummary(OtherExpenseEnum.EXPENSE_TIME.getAttrName(), timeStr));
            //支付方式
            String payMethod = payMethodMap.getOrDefault(data.getString(OtherExpenseEnum.PAY_METHOD.getAttr()), "");
            summaryList.add(commonHelp.setSummary(OtherExpenseEnum.PAY_METHOD.getAttrName(), payMethod));
            //金额封装
            JSONObject others = new JSONObject();
            BigDecimal amount = data.getBigDecimal(OtherExpenseEnum.AMOUNT.getAttr());
            String amountStr = StringUtil.formatDouble(amount);
            amountStr = amountStr + UnitEnum.MONEY.getName();
            others.put(BasicConstant.AMOUNT, amountStr);
            //汇总
            Long otherExpenseId = entityExt.getId();
            JSONObject superScript = new JSONObject();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            appListPojos.add(new AppListPojo(otherExpenseId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 移动端其他收入列表数据返回
     *
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @param resultThroughDTO
     * @return
     */
    private ResultThroughVO formatOtherIncome4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.OTHER_INCOME.getCode());
        Set<String> userIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(OtherIncomeEnum.BELONG_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //支付方式
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.OTHER_INCOME.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        Map<String, String> payMethodMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.OTHER_INCOME_PAY_METHOD, corpid, formId);
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<FormTitlePoJo> titleList = new ArrayList<>();
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            JSONObject data = entityExt.getData();
            //负责人
            String belongUser = userNameMap.getOrDefault(data.getString(OtherIncomeEnum.BELONG_ID.getAttr()), "");
            summaryList.add(commonHelp.setSummary(OtherIncomeEnum.BELONG_ID.getAttrName(), belongUser));
            //收款日期
            String timeStr = "";
            Long time = data.getLong(OtherIncomeEnum.INCOME_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            summaryList.add(commonHelp.setSummary(OtherIncomeEnum.INCOME_TIME.getAttrName(), timeStr));
            //支付方式
            String payMethod = payMethodMap.getOrDefault(data.getString(OtherIncomeEnum.PAY_METHOD.getAttr()), "");
            summaryList.add(commonHelp.setSummary(OtherIncomeEnum.PAY_METHOD.getAttrName(), payMethod));
            //金额封装
            JSONObject others = new JSONObject();
            BigDecimal amount = data.getBigDecimal(OtherIncomeEnum.AMOUNT.getAttr());
            String amountStr = StringUtil.formatDouble(amount);
            amountStr = amountStr + UnitEnum.MONEY.getName();
            others.put(BasicConstant.AMOUNT, amountStr);
            //汇总
            Long otherIncomeId = entityExt.getId();
            JSONObject superScript = new JSONObject();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            appListPojos.add(new AppListPojo(otherIncomeId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化其他支出
     *
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @param resultThroughDTO
     * @return
     */
    private ResultThroughVO formatOtherExpense(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        List<OtherExpenseEnum> otherExpenseEnumList = Arrays.asList(OtherExpenseEnum.BELONG_ID, OtherExpenseEnum.SHEET_NO, OtherExpenseEnum.AMOUNT,
                OtherExpenseEnum.EXPENSE_TIME, OtherExpenseEnum.PAY_METHOD);
        List<TitlePojo> title = new ArrayList<>();
        for (OtherExpenseEnum otherExpenseEnum : otherExpenseEnumList) {
            title.add(new TitlePojo(otherExpenseEnum.getAttr(), otherExpenseEnum.getAttrName(), otherExpenseEnum.getFieldType()));
        }
        //申请人ids
        Set<String> userIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(OtherExpenseEnum.BELONG_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.OTHER_EXPENSE.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的支付方式
        Map<String, String> payMethodMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.OTHER_EXPENSE_PAY_METHOD, corpid, formId);
        int refType4OtherExpense = XbbRefTypeEnum.OTHER_EXPENSE.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long otherExpenseId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String belongUser = userNameMap.getOrDefault(data.getString(OtherExpenseEnum.BELONG_ID.getAttr()), "");
            String no = entityExt.getSerialNo();
            BigDecimal amount = data.getBigDecimal(OtherExpenseEnum.AMOUNT.getAttr());
            String timeStr = "";
            Long time = data.getLong(OtherExpenseEnum.EXPENSE_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String payMethod = payMethodMap.getOrDefault(data.getString(OtherExpenseEnum.PAY_METHOD.getAttr()), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(OtherExpenseEnum.BELONG_ID.getAttr(), new TableDataInfoPojo(belongUser));
            jsonObject.put(OtherExpenseEnum.SHEET_NO.getAttr(), new TableDataInfoPojo(no, 1, refType4OtherExpense, otherExpenseId));
            jsonObject.put(OtherExpenseEnum.AMOUNT.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(amount)));
            jsonObject.put(OtherExpenseEnum.EXPENSE_TIME.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(OtherExpenseEnum.PAY_METHOD.getAttr(), new TableDataInfoPojo(payMethod));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化返回其他收入
     *
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @param resultThroughDTO
     * @return
     */
    private ResultThroughVO formatOtherIncome(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        List<OtherIncomeEnum> otherIncomeEnumList = Arrays.asList(OtherIncomeEnum.BELONG_ID,OtherIncomeEnum.SHEET_NO, OtherIncomeEnum.AMOUNT,
                OtherIncomeEnum.INCOME_TIME, OtherIncomeEnum.PAY_METHOD);
        List<TitlePojo> title = new ArrayList<>();
        for (OtherIncomeEnum otherIncomeEnum : otherIncomeEnumList) {
            title.add(new TitlePojo(otherIncomeEnum.getAttr(), otherIncomeEnum.getAttrName(), otherIncomeEnum.getFieldType()));
        }
        //负责人
        Set<String> userIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(OtherIncomeEnum.BELONG_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //获取启用的支付方式
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.OTHER_INCOME.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        Map<String, String> payMethodMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.OTHER_INCOME_PAY_METHOD, corpid, formId);
        int refType4OtherIncome = XbbRefTypeEnum.OTHER_INCOME.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long otherIncomeId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String belongUser = userNameMap.getOrDefault(data.getString(OtherIncomeEnum.BELONG_ID.getAttr()), "");
            String no = entityExt.getSerialNo();
            BigDecimal amount = data.getBigDecimal(OtherIncomeEnum.AMOUNT.getAttr());
            String timeStr = "";
            Long time = data.getLong(OtherIncomeEnum.INCOME_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String payMethod = payMethodMap.getOrDefault(data.getString(OtherIncomeEnum.PAY_METHOD.getAttr()), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(OtherIncomeEnum.BELONG_ID.getAttr(), new TableDataInfoPojo(belongUser));
            jsonObject.put(OtherIncomeEnum.SHEET_NO.getAttr(), new TableDataInfoPojo(no, 1, refType4OtherIncome, otherIncomeId));
            jsonObject.put(OtherIncomeEnum.AMOUNT.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(amount)));
            jsonObject.put(OtherIncomeEnum.INCOME_TIME.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(OtherIncomeEnum.PAY_METHOD.getAttr(), new TableDataInfoPojo(payMethod));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 移动端返回数据
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @return
     */
    private ResultThroughVO formatClue4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CLUE.getCode());
        //签订人ids、合同ids、客户id
        Set<Long> clueIds = new HashSet<>();
        Set<String> createIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            clueIds.add(entityExt.getId());
            createIds.add(entityExt.getCreatorId());
        }
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, createIds);
        List<PaasFormDataEntity> teamUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_CLUE_TEAM, corpid, clueIds, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<CustomerUserEntity> userTeamEntities = (List<CustomerUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_CLUE_TEAM, teamUserList);
        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(userTeamEntities);
        Map<Object, String> statusText = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, FieldAttrEntity> fieldAttrEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> configFormIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> configFormIdIn.add(entityExt.getFormId()));
        Map<Long, String> formLastConnectTime = formLastConnectTime(corpid, XbbRefTypeEnum.CLUE.getCode(), configFormIdIn);
        if (CollectionsUtil.isNotEmpty(list)) {
            Long formId = list.get(0).getFormId();
            PaasFormExplainEntity byFormId = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(byFormId)) {
                throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
            }
            fieldAttrEntityMap = ExplainUtil.getExplainMap(byFormId.getExplains());
            FieldAttrEntity fieldAttrEntity = fieldAttrEntityMap.get(ClueEnum.CLUE_STATUS.getAttr());
            List<ItemPoJo> items = fieldAttrEntity.getItems();
            items.forEach(item->{
                statusText.put(item.getValue(), item.getText());
            });
        }
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(clueIds, corpid, XbbRefTypeEnum.REFUND.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean companyNameHide;
        Boolean ownerIdHide;
        Boolean createIdHide;
        Boolean clusStatusHide;
        Boolean lastTimeHide;
        // 企业名称 负责人 创建人 线索状态 最后跟进时间
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            Long formId = entityExt.getFormId();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long clueId = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(clueId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(clueId, new ArrayList<>()));
            companyNameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.COMPANY_NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            ownerIdHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.OWNER_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            createIdHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.CREATOR_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            clusStatusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.CLUE_STATUS.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            lastTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.LAST_CONNECT_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);



            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String companyName = data.getString(ClueEnum.COMPANY_NAME.getAttr());
            String ownerName = ownerNameMap.getOrDefault(entityExt.getDataId(), "");
            String createId = entityExt.getCreatorId();
            String createName = userNameMap.getOrDefault(createId, "");
            String clueStatus = data.getString(ClueEnum.CLUE_STATUS.getAttr());
            String clueStatusText = statusText.getOrDefault(clueStatus, "");
            Long lastTime = data.getLong(ClueEnum.LAST_CONNECT_TIME.getAttr());
            Long addTime = entityExt.getAddTime();
            // if (companyNameHide){
            //     companyName ="";
            // }
            // summaryList.add(commonHelp.setSummary(ClueEnum.COMPANY_NAME.getAttrName() + ":", companyName));
            if (ownerIdHide){
                ownerName="";
            }
            summaryList.add(commonHelp.setSummary(ClueEnum.OWNER_ID.getAttrName(), ownerName));
            if (createIdHide){
                createName ="";
            }
            summaryList.add(commonHelp.setSummary(ClueEnum.CREATOR_ID.getAttrName(), createName));

            if (clusStatusHide){
                clueStatusText = "--";
            }
            summaryList.add(commonHelp.setSummary(ClueEnum.CLUE_STATUS.getAttrName(), clueStatusText));
            String lastConnectStr = "--";
            if(Objects.equals(formLastConnectTime.get(formId), "0")){
                lastConnectStr = DateUtil.getString(lastTime * 1000L, DateUtil.SDFYMDHM);
            } else {
                lastConnectStr = DateTimeUtil.getLastConnectTimeStr(lastTime);
            }

            summaryList.add(commonHelp.setSummary(ClueEnum.LAST_CONNECT_TIME.getAttrName(), lastConnectStr));

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();

            titleList.add(commonHelp.setTitle(companyName));
            appListPojos.add(new AppListPojo(clueId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化线索数据
     * @param corpid
     * @param list
     * @param resultThroughVo
     * @return
     */
    private ResultThroughVO formatClue(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        ClueEnum companyName = ClueEnum.COMPANY_NAME;
        ClueEnum clueStatus = ClueEnum.CLUE_STATUS;
        ClueEnum lastConnectTime = ClueEnum.LAST_CONNECT_TIME;
        ClueEnum addTime = ClueEnum.ADD_TIME;
        ClueEnum creatorId = ClueEnum.CREATOR_ID;
        ClueEnum ownerId = ClueEnum.OWNER_ID;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(companyName.getAttr(), companyName.getAttrName(), companyName.getFieldType()));
        title.add(new TitlePojo(clueStatus.getAttr(), clueStatus.getAttrName(), clueStatus.getFieldType()));
        title.add(new TitlePojo(lastConnectTime.getAttr(), lastConnectTime.getAttrName(), lastConnectTime.getFieldType()));
        title.add(new TitlePojo(addTime.getAttr(), addTime.getAttrName(), addTime.getFieldType()));
        title.add(new TitlePojo(creatorId.getAttr(), creatorId.getAttrName(), creatorId.getFieldType()));
        title.add(new TitlePojo(ownerId.getAttr(), ownerId.getAttrName()));
        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> clueIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            clueIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(entityExt.getCreatorId());
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<PaasFormDataEntity> userTeamEntities = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_CLUE_TEAM, corpid, clueIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<ClueUserEntity> teamUserList = (List<ClueUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_CLUE_TEAM, userTeamEntities);

        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        // 线索状态
         int refType = XbbRefTypeEnum.CLUE.getCode();
        //最终结果
        // 跟进时间展示格式
        List<Long> configFormIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> configFormIdIn.add(entityExt.getFormId()));
        Map<Long, String> formLastConnectTime = formLastConnectTime(corpid, XbbRefTypeEnum.CLUE.getCode(), configFormIdIn);

        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            Long formId = entityExt.getFormId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String name = getStringOrDefault(data, companyName.getAttr(), "");
            String timeStr = "--";
            if(Objects.equals(formLastConnectTime.get(formId), "0")){
                Long time = data.getLong(lastConnectTime.getAttr());
                timeStr = DateUtil.getString(time * 1000L, DateUtil.SDFYMDHM);
            } else {
                timeStr = DateTimeUtil.getLastConnectTimeStr(data.getLong(lastConnectTime.getAttr()));
            }
            String orDefault = entityExt.getData().getOrDefault(ClueEnum.CLUE_STATUS.getAttr(), "").toString();
            ClueStatusEnum clueStatusEnum = ClueStatusEnum.getByCode(orDefault);
            String status = Objects.nonNull(clueStatusEnum) ? clueStatusEnum.getName() : "--";
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            String owner = ownerNameMap.getOrDefault(id, "");

            JSONObject jsonObject = new JSONObject();
            jsonObject.put(companyName.getAttr(), new TableDataInfoPojo(name, 1, refType, id));
            jsonObject.put(clueStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(lastConnectTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(addTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
            jsonObject.put(creatorId.getAttr(), new TableDataInfoPojo(creator));
            jsonObject.put(ownerId.getAttr(), new TableDataInfoPojo(owner));


            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的客户业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/4/30 20:32
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatCustomer(boolean customerFunnelChart, boolean customerLoseReasonChart, boolean customerBeforeStageChart,
                                           String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        CustomerManagementEnum enumName = CustomerManagementEnum.NAME;
        CustomerManagementEnum enumType = CustomerManagementEnum.TYPE;
        CustomerManagementEnum enumBeforeStage = CustomerManagementEnum.CUSTOMER_STAGE;
        CustomerManagementEnum enumWastage = CustomerManagementEnum.WASTAGE;
        CustomerManagementEnum enumWastageMemo = CustomerManagementEnum.WASTAGE_MEMO;
        CustomerManagementEnum enumTime = CustomerManagementEnum.LAST_CONNECT_TIME;
        CustomerManagementEnum enumAddTime = CustomerManagementEnum.ADD_TIME;
        CustomerManagementEnum enumCreator = CustomerManagementEnum.CREATOR;
        CustomerManagementEnum enumOwner = CustomerManagementEnum.OWNER_ID;
        String customerLoseTime = "loseTime";
        String customerOwnerDepartment = "ownerDepartment";

        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName()));

        // 其他穿透页
        if(!customerFunnelChart && !customerLoseReasonChart && !customerBeforeStageChart){
            title.add(new TitlePojo(enumType.getAttr(), enumType.getAttrName(), enumType.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
            title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
            title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
            //还要拼负责人
            title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
        }
        // 客户阶段漏斗
        if(customerFunnelChart){
            title.add(new TitlePojo(enumType.getAttr(), enumType.getAttrName(), enumType.getFieldType()));
            title.add(new TitlePojo(enumBeforeStage.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), enumBeforeStage.getFieldType()));
            title.add(new TitlePojo(enumWastage.getAttr(), enumWastage.getAttrName(), enumWastage.getFieldType()));
            title.add(new TitlePojo(enumWastageMemo.getAttr(), enumWastageMemo.getAttrName(), enumWastageMemo.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
            title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
            title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
            //还要拼负责人
            title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
        }
        // 客户流失原因
        if(customerLoseReasonChart){
            title.add(new TitlePojo(enumType.getAttr(), enumType.getAttrName(), enumType.getFieldType()));
            title.add(new TitlePojo(enumBeforeStage.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), enumBeforeStage.getFieldType()));
            title.add(new TitlePojo(enumWastageMemo.getAttr(), enumWastageMemo.getAttrName(), enumWastageMemo.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
            title.add(new TitlePojo(customerLoseTime, I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_TIME)));
            title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
            title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
            //还要拼负责人
            title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
        }
        // 客户流失前阶段
        if(customerBeforeStageChart){
            title.add(new TitlePojo(enumBeforeStage.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), enumBeforeStage.getFieldType()));
            title.add(new TitlePojo(enumWastage.getAttr(), enumWastage.getAttrName(), enumWastage.getFieldType()));
            title.add(new TitlePojo(enumWastageMemo.getAttr(), enumWastageMemo.getAttrName(), enumWastageMemo.getFieldType()));
            title.add(new TitlePojo(customerLoseTime, I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_TIME)));
            title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
            title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
            //还要拼负责人
            title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
            //负责人所属部门
            title.add(new TitlePojo(customerOwnerDepartment, I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_OWNER_DEPARTMENT)));
        }
        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            customerIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumCreator.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        IndexTypeEnum teamIndex = indexTypeModel.getCustomerTeamIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntity> teamUserList = formHelp.getUserTeamListByIds(teamIndex, corpid, customerIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<CustomerUserEntity> userTeamEntities = (List<CustomerUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(teamIndex, teamUserList);
        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(userTeamEntities);
        //获取启用的客户状态
        Map<String, String> customerStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CUSTOMER_STATUS, corpid, null);
        int refType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        // 跟进时间展示格式
        List<Long> configFormIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> configFormIdIn.add(entityExt.getFormId()));
        Map<Long, String> formLastConnectTime = formLastConnectTime(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), configFormIdIn);

        List<Long> stageLogCustomerIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> stageLogCustomerIdIn.add(entityExt.getId()));

        // 获取所有的客户流失前的状态值
        Map<Long, String> customerIdAndBeforeStageNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerFunnelChart || customerLoseReasonChart || customerBeforeStageChart){
            String stageCorpid = configFormIdIn.size() == 0 ? "0" : corpid;
            Long stageFormId = configFormIdIn.size() == 0 ? null : configFormIdIn.get(0);
            List<CustomerStageEntity> stageList = customerStageModel.getList(stageCorpid,stageFormId, null);
            Map<String, String> stageCodeName = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            stageList.forEach(stage -> stageCodeName.put(stage.getCode(), stage.getName()));
            customerIdAndBeforeStageNameMap = customerStageLogModel.getCustomerLoseBeforeStage(corpid, stageLogCustomerIdIn, stageCodeName);
        }
        // 获取所有的客户流失的流失时间
        Map<Long, Long> customerIdAndLoseTimeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerLoseReasonChart || customerBeforeStageChart){
            customerIdAndLoseTimeMap = customerStageLogModel.getCustomerLoseTime(corpid, stageLogCustomerIdIn);
        }
        // 获取客户负责人对应的所属部门
        Map<Long, String> userAndDepartmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerBeforeStageChart){
            List<String> customerOwnerIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userTeamEntities.forEach(customerUserEntity -> customerOwnerIdIn.add(customerUserEntity.getUserId()));
            Map<String, String> nameUserDepsMap = userModel.getUserBelongDeptNameMap(corpid, customerOwnerIdIn);

            userTeamEntities.forEach(item -> {
                String owerId = item.getUserId();
                String departmentName = nameUserDepsMap.get(owerId) == null ? "" : nameUserDepsMap.get(owerId);
                userAndDepartmentMap.put(item.getDataId(), departmentName);
            });
        }

        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            Long formId = entityExt.getFormId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String name = getStringOrDefault(data, enumName.getAttr(), "");
            String type = customerStatusMap.getOrDefault(data.getString(enumType.getAttr()), "");

            String beforeStage = "--";
            String wastage = "--";
            String wastageMemo = "";
            if(customerFunnelChart || customerLoseReasonChart || customerBeforeStageChart){
                beforeStage = customerIdAndBeforeStageNameMap.getOrDefault(id, "--");
                String wastageStr = data.getString(enumWastage.getAttr());
                wastage = getCustomerWastage(corpid, formId, wastageStr);
                wastageMemo = getStringOrDefault(data, enumWastageMemo.getAttr(), "");
            }
            String loseTimeStr = "--";
            if(customerLoseReasonChart || customerBeforeStageChart){
                Long loseTime = customerIdAndLoseTimeMap.get(id);
                loseTimeStr = loseTime == null ? loseTimeStr : DateUtil.getString(loseTime * 1000L, DateUtil.SDFYMDHM);
            }

            String timeStr = "--";
            if(Objects.equals(formLastConnectTime.get(formId), "0")){
                Long time = data.getLong(enumTime.getAttr());
                timeStr = DateUtil.getString(time * 1000L, DateUtil.SDFYMDHM);
            } else {
                timeStr = DateTimeUtil.getLastConnectTimeStr(data.getLong(enumTime.getAttr()));
            }
            String creator = userNameMap.getOrDefault(data.getString(enumCreator.getAttr()), "");
            String owner = ownerNameMap.getOrDefault(id, "");
            //客户名称，可以穿透
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType, id));

            // 其他穿透页
            if(!customerFunnelChart && !customerLoseReasonChart && !customerBeforeStageChart){
                jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(type));
                jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
                jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
                jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
                jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
            }
            // 客户阶段漏斗
            if(customerFunnelChart){
                jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(type));
                jsonObject.put(enumBeforeStage.getAttr(), new TableDataInfoPojo(beforeStage));
                jsonObject.put(enumWastage.getAttr(), new TableDataInfoPojo(wastage));
                jsonObject.put(enumWastageMemo.getAttr(), new TableDataInfoPojo(wastageMemo));
                jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
                jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
                jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
                jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
            }
            // 客户流失原因
            if(customerLoseReasonChart){
                jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(type));
                jsonObject.put(enumBeforeStage.getAttr(), new TableDataInfoPojo(beforeStage));
                jsonObject.put(enumWastageMemo.getAttr(), new TableDataInfoPojo(wastageMemo));
                jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
                jsonObject.put(customerLoseTime, new TableDataInfoPojo(loseTimeStr));
                jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
                jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
                jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
            }
            // 客户流失前阶段
            if(customerBeforeStageChart){
                jsonObject.put(enumBeforeStage.getAttr(), new TableDataInfoPojo(beforeStage));
                jsonObject.put(enumWastage.getAttr(), new TableDataInfoPojo(wastage));
                jsonObject.put(enumWastageMemo.getAttr(), new TableDataInfoPojo(wastageMemo));
                jsonObject.put(customerLoseTime, new TableDataInfoPojo(loseTimeStr));
                jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
                jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
                jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
                jsonObject.put(customerOwnerDepartment, new TableDataInfoPojo(userAndDepartmentMap.get(id)));
            }
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 图表中心跟进时间展示格式
     * @param corpid 公司
     * @param businessType 业务
     * @param configFormIdIn 表单list
     * @return
     */
    private Map<Long, String> formLastConnectTime(String corpid, Integer businessType, List<Long> configFormIdIn){
        Map<Long, String> formLastConnectTime = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String typeTime = "0";
        if(Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())){
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(ParameterConstant.CORPID, corpid);
            map.put(StringConstant.BUSINESS_TYPE, businessType);
            map.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            map.put("formIdIn", configFormIdIn);
            List<FormConfigEntity> formConfigEntities = formConfigModel.findEntitys(map);

            for(FormConfigEntity entity : formConfigEntities) {
                Long formId = entity.getFormId();
                if(Objects.equals(entity.getConfig(), FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfig())) {
                    typeTime = entity.getConfigValue();
                    formLastConnectTime.put(formId, typeTime);
                    continue;
                }
                if(Objects.equals(entity.getConfig(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfig())) {
                    typeTime = entity.getConfigValue();
                    formLastConnectTime.put(formId, typeTime);
                }
                if(Objects.equals(entity.getConfig(), FormConfigEnum.CLUE_LAST_CONNECT_TIME.getConfig())) {
                    typeTime = entity.getConfigValue();
                    formLastConnectTime.put(formId, typeTime);
                }
            }
            if(formLastConnectTime.isEmpty()){
                for(FormConfigEntity entity : formConfigEntities) {
                    Long formId = entity.getFormId();
                    if(Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())){
                        formLastConnectTime.put(formId, "1");
                        continue;
                    }
                    if(Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())){
                        formLastConnectTime.put(formId, "1");
                    }
                    if(Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())){
                        formLastConnectTime.put(formId, "1");
                    }
                }
            }
        }
        return formLastConnectTime;
    }

    /**
     * app端：格式化穿透后的客户业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/12 16:15
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatCustomer4App(boolean customerFunnelChart, boolean customerLoseReasonChart, boolean customerBeforeStageChart,
                                               String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            customerIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(CustomerManagementEnum.CREATOR.getAttr()));
        }
        // 获取退字标签
        Map<Long, TagLinkEntity> tagMap = tagLinkModel.getPublicTagLink(corpid, customerIdIn, XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode());
        //有提醒的客户
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(customerIdIn, corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), pushNotifyList);
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        IndexTypeEnum teamIndex = indexTypeModel.getCustomerTeamIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntity> teamUserList = formHelp.getUserTeamListByIds(teamIndex, corpid, customerIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<CustomerUserEntity> userTeamEntities = (List<CustomerUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(teamIndex, teamUserList);
        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(userTeamEntities);
        //获取启用的客户状态
        Map<String, String> customerStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CUSTOMER_STATUS, corpid, null);
        //最终结果
        // 跟进时间展示格式
        List<Long> configFormIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> configFormIdIn.add(entityExt.getFormId()));
        Map<Long, String> formLastConnectTime = formLastConnectTime(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), configFormIdIn);

        List<Long> stageLogCustomerIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        list.forEach(entityExt -> stageLogCustomerIdIn.add(entityExt.getId()));
        // 获取所有的客户流失前的状态值
        Map<Long, String> customerIdAndBeforeStageNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerFunnelChart || customerLoseReasonChart || customerBeforeStageChart){
            String stageCorpid = configFormIdIn.size() == 0 ? "0" : corpid;
            Long stageFormId = configFormIdIn.size() == 0 ? null : configFormIdIn.get(0);
            List<CustomerStageEntity> stageList = customerStageModel.getList(stageCorpid,stageFormId, null);
            Map<String, String> stageCodeName = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            stageList.forEach(stage -> stageCodeName.put(stage.getCode(), stage.getName()));
            customerIdAndBeforeStageNameMap = customerStageLogModel.getCustomerLoseBeforeStage(corpid, stageLogCustomerIdIn, stageCodeName);
        }
        // 获取所有的客户流失的流失时间
        Map<Long, Long> customerIdAndLoseTimeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerLoseReasonChart || customerBeforeStageChart){
            customerIdAndLoseTimeMap = customerStageLogModel.getCustomerLoseTime(corpid, stageLogCustomerIdIn);
        }
        // 获取客户负责人对应的所属部门
        Map<Long, String> userAndDepartmentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(customerBeforeStageChart){
            List<String> customerOwnerIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userTeamEntities.forEach(customerUserEntity -> customerOwnerIdIn.add(customerUserEntity.getUserId()));
            Map<String, String> nameUserDepsMap = userModel.getUserBelongDeptNameMap(corpid, customerOwnerIdIn);

            userTeamEntities.forEach(item -> {
                String owerId = item.getUserId();
                String departmentName = nameUserDepsMap.get(owerId) == null ? "" : nameUserDepsMap.get(owerId);
                userAndDepartmentMap.put(item.getDataId(), departmentName);
            });
        }

        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            Long customerId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String name = getStringOrDefault(data, CustomerManagementEnum.NAME.getAttr(), "");
            String type = customerStatusMap.getOrDefault(data.getString(CustomerManagementEnum.TYPE.getAttr()), "");
            String creator = userNameMap.getOrDefault(data.getString(CustomerManagementEnum.CREATOR.getAttr()), "");
            String owner = ownerNameMap.getOrDefault(customerId, "");
            Integer isAchived = (Integer) data.getOrDefault(CustomerManagementEnum.IS_ARCHIVED.getAttr(), 0);

            String beforeStage = "--";
            String wastage = "--";
            String wastageMemo = "";
            if(customerFunnelChart || customerLoseReasonChart || customerBeforeStageChart){
                beforeStage = customerIdAndBeforeStageNameMap.getOrDefault(customerId, "--");
                String wastageStr = data.getString(CustomerManagementEnum.WASTAGE.getAttr());
                wastage = getCustomerWastage(corpid, formId, wastageStr);
                wastageMemo = getStringOrDefault(data, CustomerManagementEnum.WASTAGE_MEMO.getAttr(), "");
            }
            String loseTimeStr = "--";
            if(customerLoseReasonChart || customerBeforeStageChart){
                Long loseTime = customerIdAndLoseTimeMap.get(customerId);
                loseTimeStr = loseTime == null ? loseTimeStr : DateUtil.getString(loseTime * 1000L, DateUtil.SDFYMDHM);
            }
            // 其他
            //最后跟进时间
            Long lastConnectTime = data.getLongValue(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
            String lastConnectStr = "--";
            if(Objects.equals(formLastConnectTime.get(formId), "0")){
                lastConnectStr = DateUtil.getString(lastConnectTime * 1000L, DateUtil.SDFYMDHM);
            } else {
                lastConnectStr = DateTimeUtil.getLastConnectTimeStr(lastConnectTime);
            }
            // 创建时间
            Long addTime = entityExt.getAddTime();
            String addTimeStr = addTime == null ? "--" : DateUtil.getString(addTime * 1000L, DateUtil.SDFYMDHM);

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            // 解释
            /*explains.add("负责人：" + owner);
            explains.add("创建人：" + creator);*/
            // 其他穿透页
            if(!customerFunnelChart && !customerLoseReasonChart && !customerBeforeStageChart){
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.OWNER_ID.getAttrName(), owner));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.CREATOR.getAttrName(), creator));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.TYPE.getAttrName(), type));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.LAST_CONNECT_TIME.getAttrName(), lastConnectStr));
            }
            // 客户阶段漏斗
            if(customerFunnelChart){
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.OWNER_ID.getAttrName(), owner));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.CREATOR.getAttrName(), creator));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.TYPE.getAttrName(), type));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), beforeStage));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.WASTAGE.getAttrName(), wastage));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.WASTAGE_MEMO.getAttrName(), wastageMemo));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.LAST_CONNECT_TIME.getAttrName(), lastConnectStr));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.ADD_TIME.getAttrName(), addTimeStr));
            }
            // 客户流失原因
            if(customerLoseReasonChart){
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.OWNER_ID.getAttrName(), owner));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.CREATOR.getAttrName(), creator));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.TYPE.getAttrName(), type));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), beforeStage));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.WASTAGE_MEMO.getAttrName(), wastageMemo));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_TIME), loseTimeStr));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.LAST_CONNECT_TIME.getAttrName(), lastConnectStr));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.ADD_TIME.getAttrName(), addTimeStr));
            }
            // 客户流失前阶段
            if(customerBeforeStageChart){
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.OWNER_ID.getAttrName(), owner));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_OWNER_DEPARTMENT), userAndDepartmentMap.get(customerId)));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.CREATOR.getAttrName(), creator));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_BEFORE_STAGE), beforeStage));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.WASTAGE.getAttrName(), wastage));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.WASTAGE_MEMO.getAttrName(), wastageMemo));
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LOSE_TIME), loseTimeStr));
                summaryList.add(commonHelp.setSummary(CustomerManagementEnum.ADD_TIME.getAttrName(), addTimeStr));
            }
            // 标签
            // 角标 -
            superScript.put("message", pushNotifyList.contains(customerId) ? 1 : 0);
            if(Objects.equals(isAchived, 1)){
                superScript.put("archived", 1);
            }
            // 退字标签
            if(tagMap.containsKey(customerId)){
                superScript.put("back", tagMap.getOrDefault(customerId, new TagLinkEntity()));
            }
            titleList.add(commonHelp.setTitle(name));
            appListPojos.add(new AppListPojo(customerId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的跟进记录业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/2 21:06
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatCommunicate(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        CustomerCommunicateEnum enumCustomerId = CustomerCommunicateEnum.CUSTOMER_NAME;
        CustomerCommunicateEnum enumType = CustomerCommunicateEnum.TYPE;
        CustomerCommunicateEnum enumTime = CustomerCommunicateEnum.COMMUNICATE_TIME;
        CustomerCommunicateEnum enumAddTime = CustomerCommunicateEnum.ADD_TIME;
        CustomerCommunicateEnum enumCreator = CustomerCommunicateEnum.CREATOR_ID;
        CustomerCommunicateEnum enumMemo = CustomerCommunicateEnum.MEMO;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo.Builder().key(enumCustomerId.getAttr()).value(enumCustomerId.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_DEFAULT.getCode()).fieldType(enumCustomerId.getFieldType()).build());
        title.add(new TitlePojo.Builder().key(enumType.getAttr()).value(enumType.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_DEFAULT.getCode()).fieldType(enumType.getFieldType()).build());
        title.add(new TitlePojo.Builder().key(enumTime.getAttr()).value(enumTime.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_DEFAULT.getCode()).fieldType(enumTime.getFieldType()).build());
        title.add(new TitlePojo.Builder().key(enumAddTime.getAttr()).value( enumAddTime.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_DEFAULT.getCode()).fieldType(enumAddTime.getFieldType()).build());
        title.add(new TitlePojo.Builder().key(enumCreator.getAttr()).value(enumCreator.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_DEFAULT.getCode()).fieldType(enumCreator.getFieldType()).build());
        title.add(new TitlePojo.Builder().key(enumMemo.getAttr()).value(enumMemo.getAttrName()).specialSymbol(SpecialSymbolEnum.SPECIAL_SYMBOL_ONE.getCode()).fieldType(enumMemo.getFieldType()).build());

        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        // 跟进记录解释
        PaasFormExplainEntity formExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), corpid);
        if (Objects.isNull(formExplainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(formExplainEntity.getExplains());
        FieldAttrEntity typeField = explainMap.get(CommunicateBaseEnum.TYPE.getAttr());
        int refTypeCustomer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            //获取启用的跟进方式
            String type = "";
            if (Objects.isNull(typeField)) {
                type = I18nMessageUtil.getMessage(StringConstant.VALUE_NOT_SET);
            } else {
                Object itemValue = ItemUtil.getCustomItemList(typeField, data);
                if (Objects.nonNull(itemValue)) {
                    type = itemValue.toString();
                }
            }
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time);
            }
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            //林斌测试公司出现数组格式备注，导致转换错误，兼容一下
            String memoStr = data.getString(enumMemo.getAttr());
            String memo = (Objects.isNull(memoStr)) ? "" : memoStr;
            //客户名称，可以穿透
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refTypeCustomer, customerId));
            jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(type));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
            jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
            jsonObject.put(enumMemo.getAttr(), new TableDataInfoPojo(memo));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的跟进记录业务
     * @param resultThroughPojo 穿透参数pojo
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/12 19:34
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatCommunicate4App(ResultThroughPojo resultThroughPojo, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode());
        String corpid = resultThroughPojo.getCorpid();
        String userId = resultThroughPojo.getUserId();
        //创建人ids、客户ids
        List<Long> dataIdIn = new ArrayList<>();
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            dataIdIn.add(entityExt.getDataId());
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr()));
        }
        dataIdIn.add(-1L);
        Map<Long, Integer> commnetCountMap = paasCommentModel.getCommnetCountMap(dataIdIn, corpid, BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode());
        Map<Long, Integer> likeCountMap = likeModel.getLikeCountMap(dataIdIn, corpid, BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode());
        List<Long> hasCommentIdList = paasCommentModel.hasMyComment(dataIdIn, corpid, BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(), userId);
        List<Long> hasLikeIdList = likeModel.hasMyLike(dataIdIn, corpid, BusinessCommentEnum.CUSTOMER_COMMUNICATE.getCode(), userId);
        //员工id--员工实体
        Map<String, UserEntity> userMap = commonHelp.getUserMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //查询出跟进记录的表单id
        //TODO getByBusinessType
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), corpid);
        //获取启用的跟进方式
        Map<String, String> typeMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.COMMUNICATE_TYPE, corpid, paasFormEntityExt.getId());
        //最终结果
        List<CustomerCommunicatePojo> customerCommunicatePojoList = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(CustomerCommunicateEnum.CUSTOMER_NAME.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String creatorId = entityExt.getCreatorId();
            UserEntity creatUser = userMap.getOrDefault(creatorId, new UserEntity());
            String userName = creatUser.getName();
            String userAvatar = creatUser.getAvatar();
            userAvatar = userAvatar == null ? "" : userAvatar;

            CustomerCommunicatePojo customerCommunicatePojo = commonHelp.setCustomerCommunicatePojo(commnetCountMap, likeCountMap, hasCommentIdList, hasLikeIdList, entityExt, data, customerId, customerName, typeMap, creatorId, userName, Collections.singletonList(userAvatar));
            customerCommunicatePojoList.add(customerCommunicatePojo);
        }
        CommunicateVO communicateVo = new CommunicateVO();
        communicateVo.setResultMap(customerCommunicatePojoList);
        communicateVo.setPageHelper(resultThroughVo.getPageHelper());
        resultThroughVo.setDataApp(communicateVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的机会业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/2 22:05
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOpportunity(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        SalesOpportunityEnum enumName = SalesOpportunityEnum.NAME;
        SalesOpportunityEnum enumNo = SalesOpportunityEnum.SERIAL_NO;
        SalesOpportunityEnum enumCustomerId = SalesOpportunityEnum.CUSTOMER_NAME;
        SalesOpportunityEnum enumSaleStage = SalesOpportunityEnum.SALE_STAGE;
        SalesOpportunityEnum enumAmount = SalesOpportunityEnum.ESTIMATE_AMOUNT;
        SalesOpportunityEnum enumTime = SalesOpportunityEnum.ESTIMATE_END_TIME;
        SalesOpportunityEnum enumAddTime = SalesOpportunityEnum.ADD_TIME;
        SalesOpportunityEnum enumCreator = SalesOpportunityEnum.CREATOR_ID;
        SalesOpportunityEnum enumOwner = SalesOpportunityEnum.OWNER_ID;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        title.add(new TitlePojo(enumSaleStage.getAttr(), enumSaleStage.getAttrName(), enumSaleStage.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
        title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
        title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
        //机会ids、创建人ids、客户ids
        Set<Long> opportunityIdIn = new HashSet<>();
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        List<Long> formIdIn = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            opportunityIdIn.add(entityExt.getId());
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            formIdIn.add(entityExt.getFormId());
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<PaasFormDataEntity> userTeamEntities = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_OPPORTUNITY_TEAM, corpid, opportunityIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<OpportunityUserEntity> teamUserList = (List<OpportunityUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_OPPORTUNITY_TEAM, userTeamEntities);
        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //阶段：0其他普通类型，1赢单，2输单，3取消，不统计输单、取消
        //List<Integer> typeIn = SaleStageTypeEnum.getAllCode();
        //获取启用的销售阶段
        Map<String, String> allStageMap = saleStageModel.getAllStageMap(corpid);
        //Map<String, String> stageMap = commonHelp.getStageMap4Opp(corpid, typeIn);
        int refTypeCustomer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        int refTypeOpportunity = XbbRefTypeEnum.SALES_OPPORTUNITY.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String name = data.getString(enumName.getAttr());
            String no = entityExt.getSerialNo();
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String stage = allStageMap.getOrDefault(entityExt.getFormId() + StringConstant.CROSS + data.getString(enumSaleStage.getAttr()), "");
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            String owner = ownerNameMap.getOrDefault(id, "");

            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refTypeOpportunity, id));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refTypeOpportunity, id));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refTypeCustomer, customerId));
            jsonObject.put(enumSaleStage.getAttr(), new TableDataInfoPojo(stage));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
            jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
            jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的机会业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/12 20:16
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOpportunity4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
        //机会ids、创建人ids、客户ids
        Set<Long> opportunityIdIn = new HashSet<>();
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        List<Long> formIdIn = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            opportunityIdIn.add(entityExt.getId());
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(SalesOpportunityEnum.CUSTOMER_NAME.getAttr()));
        }
        //有提醒的机会
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(opportunityIdIn, corpid, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), pushNotifyList);
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<PaasFormDataEntity> opportunityUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_OPPORTUNITY_TEAM, corpid, opportunityIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<OpportunityUserEntity> teamUserList = (List<OpportunityUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_OPPORTUNITY_TEAM, opportunityUserList);
        //customerId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));

        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //阶段：0其他普通类型，1赢单，2输单，3取消，不统计输单、取消
        //List<Integer> typeIn = SaleStageTypeEnum.getAllCode();
        //获取所有销售阶段
        Map<String, String> allStageMap = saleStageModel.getAllStageMap(corpid);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long id = entityExt.getId();
            long appId = entityExt.getAppId();
            long menuId = entityExt.getMenuId();
            long formId = entityExt.getFormId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(SalesOpportunityEnum.CUSTOMER_NAME.getAttr());
            String name = data.getString(SalesOpportunityEnum.NAME.getAttr());
            String no = entityExt.getSerialNo();
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String staleStage = allStageMap.getOrDefault(entityExt.getFormId() + StringConstant.CROSS + data.getString(SalesOpportunityEnum.SALE_STAGE.getAttr()), "");
            String timeStr = "";
            Long time = data.getLong(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            String owner = ownerNameMap.getOrDefault(id, "");

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            // 解释
            if(!StringUtil.isEmpty(owner)){
                //explains.add("负责人：" + owner);
                summaryList.add(commonHelp.setSummary(SalesOpportunityEnum.OWNER_ID.getAttrName(), owner));
            }
            if(!StringUtil.isEmpty(creator)){
                //explains.add("创建人：" + creator);
                summaryList.add(commonHelp.setSummary(SalesOpportunityEnum.CREATOR_ID.getAttrName(), creator));
            }
            //explains.add("关联客户：" + customerName);
            summaryList.add(commonHelp.setSummary(SalesOpportunityEnum.CUSTOMER_NAME.getAttrName(), customerName));
            String estimateEndTimeStr = SalesOpportunityEnum.ESTIMATE_END_TIME.getAttrName() + "：";
            //explains.add(estimateEndTimeStr + timeStr);
            summaryList.add(commonHelp.setSummary(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttrName(), timeStr));
            // 角标
            superScript.put("message", pushNotifyList.contains(id) ? 1 : 0);
            /*-- 其他 -*/
            //格式化钱币
            String amountFormat = StringUtil.formatDouble(data.getDoubleValue(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr()));
            others.put("amount", amountFormat);
            others.put("salesStage", staleStage);

            titleList.add(commonHelp.setTitle(name));

            appListPojos.add(new AppListPojo(id, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的合同业务（合同数量不考虑业绩分配，红冲合同要跳转至退货退款）
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/2 17:27
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatContract(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        if (IndicatorRuleEnum.RED_CONTRACT == indicatorRuleEnum) {
            return formatRefund(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
        }
        ContractEnum enumName = ContractEnum.NAME;
        ContractEnum enumNo = ContractEnum.CONTRACT_NO;
        ContractEnum enumAmount = ContractEnum.AMOUNT;
        ContractEnum enumStatus = ContractEnum.STATUS;
        ContractEnum enumCustomerId = ContractEnum.LINK_CUSTOMER;
        ContractEnum enumSignPerson = ContractEnum.SIGN_PERSON;
        ContractEnum enumTime = ContractEnum.SIGN_TIME;
        ContractEnum enumDeadline = ContractEnum.DEADLINE;
        ContractEnum enumSignName = ContractEnum.SIGN_NAME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(),enumAmount.getFieldType()));
        if (IndicatorRuleEnum.CONTRACT_PROFIT == indicatorRuleEnum) {
            //合同毛利、现金毛利则需要加两列：合同成本、现金/合同毛利
            title.add(new TitlePojo(ContractEnum.CONTRACT_COST.getAttr(), ContractEnum.CONTRACT_COST.getAttrName(), ContractEnum.CONTRACT_COST.getFieldType()));
            title.add(new TitlePojo(ContractEnum.GROSS_PROFIT.getAttr(), ContractEnum.GROSS_PROFIT.getAttrName(), ContractEnum.GROSS_PROFIT.getFieldType()));
        } else if (IndicatorRuleEnum.CONTRACT_PROFIT_CASH == indicatorRuleEnum) {
            //合同毛利、现金毛利则需要加两列：合同成本、现金/合同毛利
            title.add(new TitlePojo(ContractEnum.CONTRACT_COST.getAttr(), ContractEnum.CONTRACT_COST.getAttrName(), ContractEnum.CONTRACT_COST.getFieldType()));
            title.add(new TitlePojo(ContractEnum.CASH_PROFIT.getAttr(), ContractEnum.CASH_PROFIT.getAttrName(), ContractEnum.CASH_PROFIT.getFieldType()));
        }
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        //签订人ids、合同ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        Map<Long, String> userNameMapStr = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entityExt : list) {
            contractIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userNameMapStr.put(entityExt.getDataId(),data.getString(enumSignName.getAttr()) + StringConstant.LEAVE_ANOTHER_MARK);
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且非数量统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum != IndicatorRuleEnum.CONTRACT_COUNT;
        if (flag) {
            title.add(new TitlePojo(enumSignPerson.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION), enumSignPerson.getFieldType()));
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, contractIdIn);
        } else {
            title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName(), enumSignPerson.getFieldType()));
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        title.add(new TitlePojo(enumDeadline.getAttr(), enumDeadline.getAttrName(), enumDeadline.getFieldType()));
        //获取启用的合同状态
        Map<String, String> contractStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CONTRACT_STATUS, corpid, null);
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean statusHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        Boolean deadLineHide;
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(id, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(id, new ArrayList<>()));
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(entityExt.getFormId(), new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumAmount.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            statusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumStatus.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumCustomerId.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumTime.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            deadLineHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumDeadline.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumSignPerson.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumName.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumNo.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String name = getStringOrDefault(data, enumName.getAttr(), "");
            String no = entityExt.getSerialNo();
            String status = contractStatusMap.getOrDefault(data.getString(enumStatus.getAttr()), "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String amount = StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()));
            //签订人or归属人
            String belongNameStr;
            if (flag) {
                belongNameStr = cidPerforInfoMap.getOrDefault(id, "");
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), userNameMapStr.getOrDefault(id,""));
            }
            String deadlineStr = "";
            Long deadline = data.getLong(enumDeadline.getAttr());
            if (deadline != null && deadline > 0) {
                deadlineStr = DateTimeUtil.getStringEpochSecond(deadline, DateTimeUtil.SDFDate);
            }
            String timeStr = DateTimeUtil.getStringEpochSecond(data.getLong(enumTime.getAttr()), DateTimeUtil.SDFDate);
            if (amountHide) {
                amount = "";
            }
            if (signPersonHide) {
                belongNameStr = "";
            }
            if (signTimeHide) {
                timeStr = "";
            }
            if (deadLineHide) {
                deadlineStr = "";
            }
            if (statusHide) {
                status = "";
            }
            TableDataInfoPojo contractNoData = new TableDataInfoPojo(no, 1, refType4Contract, id);
            if (noHide) {
                contractNoData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo contractNameData = new TableDataInfoPojo(name, 1, refType4Contract, id);
            if (nameHide) {
                contractNameData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo customerData = new TableDataInfoPojo(customerName, 1, refType4Customer, customerId);
            if (linkCustomerHide) {
                customerData = new TableDataInfoPojo("");
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), contractNameData);
            jsonObject.put(enumNo.getAttr(), contractNoData);
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(amount));
            if (IndicatorRuleEnum.CONTRACT_PROFIT == indicatorRuleEnum) {
                //合同毛利、现金毛利则需要加两列：合同成本、现金/合同毛利
                Boolean costHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CONTRACT_COST.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                Boolean grossProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.GROSS_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                String costStr = StringUtil.formatDouble(data.getDoubleValue(ContractEnum.CONTRACT_COST.getAttr()));
                String grossProfitStr = StringUtil.formatDouble(data.getDoubleValue(ContractEnum.GROSS_PROFIT.getAttr()));
                if (costHide) {
                    costStr = "";
                }
                if (grossProfitHide) {
                    grossProfitStr = "";
                }
                jsonObject.put(ContractEnum.CONTRACT_COST.getAttr(), new TableDataInfoPojo(costStr));
                jsonObject.put(ContractEnum.GROSS_PROFIT.getAttr(), new TableDataInfoPojo(grossProfitStr));
            } else if (IndicatorRuleEnum.CONTRACT_PROFIT_CASH == indicatorRuleEnum) {
                //合同毛利、现金毛利则需要加两列：合同成本、现金/合同毛利
                Boolean costHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CONTRACT_COST.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                Boolean cashProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CASH_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                String costStr = StringUtil.formatDouble(data.getDoubleValue(ContractEnum.CONTRACT_COST.getAttr()));
                String cashProfitStr = StringUtil.formatDouble(data.getDoubleValue(ContractEnum.CASH_PROFIT.getAttr()));
                if (costHide) {
                    costStr = "";
                }
                if (cashProfitHide) {
                    cashProfitStr = "";
                }
                jsonObject.put(ContractEnum.CONTRACT_COST.getAttr(), new TableDataInfoPojo(costStr));
                jsonObject.put(ContractEnum.CASH_PROFIT.getAttr(), new TableDataInfoPojo(cashProfitStr));
            }
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumCustomerId.getAttr(), customerData);
            jsonObject.put(enumSignPerson.getAttr(), new TableDataInfoPojo(belongNameStr));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumDeadline.getAttr(), new TableDataInfoPojo(deadlineStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的订单业务
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2020/1/14 17:27
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOrder(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        if (IndicatorRuleEnum.ORDER_PROFIT == indicatorRuleEnum) {
            return formatOrderProfit(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
        }
        OrderEnum enumNo = OrderEnum.ORDER_NO; //订单编号
        OrderEnum enumAmount = OrderEnum.AMOUNT; //订单金额
        //经销商
        OrderEnum enumLinkCustomer = OrderEnum.LINK_DISTRIBUTOR;
        OrderEnum enumSignPerson = OrderEnum.SIGN_PERSON;//签订人
        OrderEnum enumTime = OrderEnum.SIGN_TIME;//下单日期
        OrderEnum enumOrderer = OrderEnum.ORDERER;//下单人
        //员工id--员工名称
        Map<String, String> userNameMap = null;
        //TODO 之后考虑要不要用CONTRACT 和 CUSTOMER_MANAGEMENT
        int refType4Order = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        Set<String> userIdIn = new HashSet<>();
        Set<Long> orderIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            orderIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            customerIdIn.add(data.getLongValue(enumLinkCustomer.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(CustomerManagementEnum.NAME.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("distributorMark",resultThroughDTO.getDistributorMark());
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(orderIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName()));
        title.add(new TitlePojo(enumLinkCustomer.getAttr(), enumLinkCustomer.getAttrName())); //留一个位置给经销商

        title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName()));
        title.add(new TitlePojo(enumOrderer.getAttr(), enumOrderer.getAttrName()));

        JSONArray resultData = new JSONArray();
        Boolean amountHide;
        Boolean noHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(id, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(id, new ArrayList<>()));
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONObject jsonObject = new JSONObject();
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(entityExt.getFormId(), new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumAmount.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumNo.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumLinkCustomer.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumTime.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            String no = entityExt.getSerialNo();
            TableDataInfoPojo orderNoData = new TableDataInfoPojo(no, 1, refType4Order, id);
            if (noHide) {
                orderNoData = new TableDataInfoPojo("");
            }
            jsonObject.put(enumNo.getAttr(), orderNoData);
            String amount = StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()));
            if (amountHide) {
                amount = "";
            }
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(amount));

            String belongNameStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), "");
            jsonObject.put(enumSignPerson.getAttr(),  new TableDataInfoPojo(belongNameStr));

            Long customerId = data.getLong(enumLinkCustomer.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            TableDataInfoPojo customerData = new TableDataInfoPojo(customerName, 1, refType4Customer, customerId);
            if (linkCustomerHide) {
                customerData = new TableDataInfoPojo("");
            }
            jsonObject.put(enumLinkCustomer.getAttr(), customerData);

            String timeStr = DateTimeUtil.getStringEpochSecond(data.getLong(enumTime.getAttr()), DateTimeUtil.SDFDate);
            if (signTimeHide) {
                timeStr = "";
            }
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));

            String ordererName = data.getString(enumOrderer.getAttr());
            jsonObject.put(enumOrderer.getAttr(), new TableDataInfoPojo(ordererName));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的订单毛利表
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2020/1/14 17:27
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOrderProfit(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {

        OrderEnum enumNo = OrderEnum.ORDER_NO; //订单编号
        OrderEnum enumAmount = OrderEnum.AMOUNT; //订单金额
        OrderEnum enumProfit = OrderEnum.GROSS_PROFIT;//订单毛利
        OrderEnum enumProfitRate = OrderEnum.GROSS_PROFIT_RATE;//订单毛利率
        OrderEnum enumLinkCustomer = OrderEnum.LINK_DISTRIBUTOR;//经销商
        OrderEnum enumSignPerson = OrderEnum.SIGN_PERSON;//签订人
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //TODO 之后考虑要不要用CONTRACT 和 CUSTOMER_MANAGEMENT
        int refType4Order = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        Set<String> userIdIn = new HashSet<>();
        Set<Long> orderIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            orderIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            customerIdIn.add(data.getLongValue(enumLinkCustomer.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(CustomerManagementEnum.NAME.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("distributorMark",resultThroughDTO.getDistributorMark());
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(orderIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName()));
        title.add(new TitlePojo(enumProfit.getAttr(), enumProfit.getAttrName()));
        title.add(new TitlePojo(enumProfitRate.getAttr(), enumProfitRate.getAttrName()));
        title.add(new TitlePojo(enumLinkCustomer.getAttr(), enumLinkCustomer.getAttrName()));
        title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName()));

        JSONArray resultData = new JSONArray();
        Boolean amountHide;
        Boolean noHide;
        Boolean linkCustomerHide;
        Boolean grossProfitHide;
        Boolean profitRateHide;
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(id, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(id, new ArrayList<>()));
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONObject jsonObject = new JSONObject();
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(entityExt.getFormId(), new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumAmount.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumNo.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumLinkCustomer.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            grossProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumProfit.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            profitRateHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumProfitRate.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            String no = entityExt.getSerialNo();
            TableDataInfoPojo orderNoData = new TableDataInfoPojo(no, 1, refType4Order, id);
            if (noHide) {
                orderNoData = new TableDataInfoPojo("");
            }
            jsonObject.put(enumNo.getAttr(), orderNoData);//编号
            String amount = StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()));
            if (amountHide) {
                amount = "";
            }
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(amount));
            //订单毛利
            String grossProfitStr = StringUtil.formatDouble(data.getDoubleValue(enumProfit.getAttr()));
            if (grossProfitHide) {
                grossProfitStr = "";
            }
            jsonObject.put(enumProfit.getAttr(), new TableDataInfoPojo(grossProfitStr));
            //订单毛利率
            String profitRateStr = StringUtil.formatDouble(data.getDoubleValue(enumProfitRate.getAttr()));
            if (profitRateHide) {
                profitRateStr = "";
            }
            jsonObject.put(enumProfitRate.getAttr(), new TableDataInfoPojo(profitRateStr));
            //经销商
            Long customerId = data.getLong(enumLinkCustomer.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            TableDataInfoPojo customerData = new TableDataInfoPojo(customerName, 1, refType4Customer, customerId);
            if (linkCustomerHide) {
                customerData = new TableDataInfoPojo("");
            }
            jsonObject.put(enumLinkCustomer.getAttr(), customerData);
            //签订人
            String belongNameStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), "");
            jsonObject.put(enumSignPerson.getAttr(),  new TableDataInfoPojo(belongNameStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的合同业务
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/13 20:43
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatContract4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        if (IndicatorRuleEnum.RED_CONTRACT == indicatorRuleEnum) {
            return formatRefund4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
        }
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
        //签订人ids、合同ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        Map<Long, String> userNameMapStr = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entityExt : list) {
            contractIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userNameMapStr.put(entityExt.getDataId(), data.getString(ContractEnum.SIGN_NAME.getAttr()) + StringConstant.LEAVE_ANOTHER_MARK);
            userIdIn.add(data.getString(ContractEnum.SIGN_PERSON.getAttr()));
            customerIdIn.add(data.getLongValue(ContractEnum.LINK_CUSTOMER.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且非数量统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum != IndicatorRuleEnum.CONTRACT_COUNT;
        if (flag) {
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, contractIdIn);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        //获取启用的合同状态
        Map<String, String> contractStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CONTRACT_STATUS, corpid, null);
        //有提醒的合同
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), pushNotifyList);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean statusHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            Long contractId = entityExt.getId();
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(contractId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(contractId, new ArrayList<>()));
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(formId, new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.AMOUNT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            statusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.STATUS.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.LINK_CUSTOMER.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_PERSON.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CONTRACT_NO.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(ContractEnum.LINK_CUSTOMER.getAttr());
            Integer isRed = (Integer) data.getOrDefault(ContractEnum.IS_RED.getAttr(), 0);
            String signTime = DateTimeUtil.getStringEpochSecond(data.getLong(ContractEnum.SIGN_TIME.getAttr()), DateTimeUtil.SDFDate);
            String name = getStringOrDefault(data, ContractEnum.NAME.getAttr(), "");
            String no = entityExt.getSerialNo();
            String status = contractStatusMap.getOrDefault(data.getString(ContractEnum.STATUS.getAttr()), "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            double amountDouble = data.getDoubleValue(ContractEnum.AMOUNT.getAttr());
            String amount = StringUtil.formatDouble(amountDouble);
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*-- 解释 -*/
            if (nameHide) {
                name = "";
            }
            if (linkCustomerHide) {
                customerName = "";
            }
            summaryList.add(commonHelp.setSummary(ContractEnum.NAME.getAttrName(), name));
            summaryList.add(commonHelp.setSummary(ContractEnum.LINK_CUSTOMER.getAttrName(), customerName));

            //签订人or归属人
            String belongNameStr;
            if (flag) {
                belongNameStr = cidPerforInfoMap.getOrDefault(contractId, "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION), belongNameStr));
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(ContractEnum.SIGN_PERSON.getAttr()), userNameMapStr.getOrDefault(contractId, ""));
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(ContractEnum.SIGN_PERSON.getAttrName(), belongNameStr));
            }
            if (signTimeHide) {
                signTime = "";
            }
            summaryList.add(commonHelp.setSummary(ContractEnum.SIGN_TIME.getAttrName(), signTime));
            if (IndicatorRuleEnum.CONTRACT_PROFIT == indicatorRuleEnum) {
                Boolean grossProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.GROSS_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                String grossProfit = data.getString(ContractEnum.GROSS_PROFIT.getAttr());
                if (grossProfitHide) {
                    grossProfit = "";
                }
                summaryList.add(commonHelp.setSummary(ContractEnum.GROSS_PROFIT.getAttrName(), grossProfit));
            } else if (IndicatorRuleEnum.CONTRACT_PROFIT_CASH == indicatorRuleEnum) {
                Boolean cashProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CASH_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                String cashProfit = data.getString(ContractEnum.CASH_PROFIT.getAttr());
                if (cashProfitHide) {
                    cashProfit = "";
                }
                summaryList.add(commonHelp.setSummary(ContractEnum.CASH_PROFIT.getAttrName(), cashProfit));
            }
            /*-- 角标 -*/
            superScript.put("message", pushNotifyList.contains(contractId) ? 1 : 0);
            /*-- 标签 -*/
            if (statusHide) {
                status = "";
            }
            lablesList.add(commonHelp.setLable(ContractEnum.STATUS.getAttrName(), status));
            if (noHide) {
                no = "";
            }
            titleList.add(commonHelp.setTitle(no));
            /*-- 其他 -*/
            if (amountHide) {
                amount = "";
            }
            others.put("amount", amount);
            others.put("isRed", isRed);
            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * app端：经销商管理》订货分析》订单数穿透
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/3/1 09:30
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOrder4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        if (IndicatorRuleEnum.ORDER_PROFIT == indicatorRuleEnum) {
            return formatOrderProfit4App(indicatorRuleEnum, corpid, openRule, list, resultThroughVo, resultThroughDTO);
        }
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
        //签订人ids、合同ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            contractIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(ContractEnum.SIGN_PERSON.getAttr()));
            customerIdIn.add(data.getLongValue(ContractEnum.LINK_CUSTOMER.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且非数量统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum != IndicatorRuleEnum.CONTRACT_COUNT;
        if (flag) {
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, contractIdIn);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
       // Map<String, String> contractStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CONTRACT_STATUS, corpid, null);
        //获取启用的合同状态
        Map<String, String> contractStatusMap = OrderStatusEnum.orderStatusMap();
        //有提醒的合同
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), pushNotifyList);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean statusHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            Long contractId = entityExt.getId();
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(contractId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(contractId, new ArrayList<>()));
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(formId, new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.AMOUNT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            statusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.STATUS.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.LINK_CUSTOMER.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_PERSON.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CONTRACT_NO.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(ContractEnum.LINK_CUSTOMER.getAttr());
            Integer isRed = (Integer) data.getOrDefault(ContractEnum.IS_RED.getAttr(), 0);
            String signTime = DateTimeUtil.getStringEpochSecond(data.getLong(ContractEnum.SIGN_TIME.getAttr()), DateTimeUtil.SDFDate);
            String name = getStringOrDefault(data, ContractEnum.NAME.getAttr(), "");
            String no = entityExt.getSerialNo();
            String status = contractStatusMap.getOrDefault(data.getString(ContractEnum.STATUS.getAttr()), "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            double amountDouble = data.getDoubleValue(ContractEnum.AMOUNT.getAttr());
            String amount = StringUtil.formatDouble(amountDouble);
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*-- 解释 -*/
            if (nameHide) {
                name = "";
            }
            if (linkCustomerHide) {
                customerName = "";
            }
            //经销商名称
            summaryList.add(commonHelp.setSummary(DistributorEnum.NAME.getAttrName(), customerName));
            //签订人or归属人
            String belongNameStr;
            if (flag) {
                belongNameStr = cidPerforInfoMap.getOrDefault(contractId, "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION), belongNameStr));
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(ContractEnum.SIGN_PERSON.getAttr()), "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(ContractEnum.SIGN_PERSON.getAttrName(), belongNameStr));
            }
            if (signTimeHide) {
                signTime = "";
            }
            summaryList.add(commonHelp.setSummary(OrderEnum.SIGN_TIME.getAttrName(), signTime));
//            if (IndicatorRuleEnum.CONTRACT_PROFIT == indicatorRuleEnum) {
//                Boolean grossProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.GROSS_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
//                String grossProfit = data.getString(ContractEnum.GROSS_PROFIT.getAttr());
//                if (grossProfitHide) {
//                    grossProfit = "";
//                }
//                summaryList.add(commonHelp.setSummary(ContractEnum.GROSS_PROFIT.getAttrName(), grossProfit));
//            } else if (IndicatorRuleEnum.CONTRACT_PROFIT_CASH == indicatorRuleEnum) {
//                Boolean cashProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CASH_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
//                String cashProfit = data.getString(ContractEnum.CASH_PROFIT.getAttr());
//                if (cashProfitHide) {
//                    cashProfit = "";
//                }
//                summaryList.add(commonHelp.setSummary(ContractEnum.CASH_PROFIT.getAttrName(), cashProfit));
//            }
            /*-- 角标 -*/
            superScript.put("message", pushNotifyList.contains(contractId) ? 1 : 0);
            /*-- 标签 -*/
            if (statusHide) {
                status = "";
            }
            lablesList.add(commonHelp.setLable(ContractEnum.STATUS.getAttrName(), status));
            if (noHide) {
                no = "";
            }
            titleList.add(commonHelp.setTitle(no));
            /*-- 其他 -*/
            if (amountHide) {
                amount = "";
            }
            others.put("amount", amount);
            others.put("isRed", isRed);
            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * app端：经销商管理》订货分析》订单毛利/订单毛利率穿透
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/3/1 09：28
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatOrderProfit4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
        //签订人ids、合同ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        String systemCode = resultThroughDTO.getSystemCode();
        for (PaasFormDataEntityExt entityExt : list) {
            contractIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(ContractEnum.SIGN_PERSON.getAttr()));
            customerIdIn.add(data.getLongValue(ContractEnum.LINK_CUSTOMER.getAttr()));
            formIds.add(entityExt.getFormId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且非数量统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum != IndicatorRuleEnum.CONTRACT_COUNT;
        if (flag) {
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, contractIdIn);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        // Map<String, String> contractStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CONTRACT_STATUS, corpid, null);
        //获取启用的合同状态
        Map<String, String> contractStatusMap = OrderStatusEnum.orderStatusMap();
        //有提醒的合同
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), pushNotifyList);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL);
        param.put("formIdIn", formIds);
        List<PaasFormExplainEntity> entityExt1 = paasFormExplainModel.findEntitys(param);
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>(entityExt1.size());
        entityExt1.forEach(item -> {
            List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(item.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> attrEntityMap = new HashMap<>(fieldAttrEntities.size());
            for (FieldAttrEntity entity : fieldAttrEntities) {
                attrEntityMap.put(entity.getAttr(), entity);
            }
            fieldMap.put(item.getFormId(), attrEntityMap);
        });
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(contractIdIn, corpid, XbbRefTypeEnum.CONTRACT.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean statusHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            Long contractId = entityExt.getId();
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(contractId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(contractId, new ArrayList<>()));
            Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(formId, new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.AMOUNT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            statusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.STATUS.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.LINK_CUSTOMER.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.SIGN_PERSON.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.CONTRACT_NO.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(ContractEnum.LINK_CUSTOMER.getAttr());
            Integer isRed = (Integer) data.getOrDefault(ContractEnum.IS_RED.getAttr(), 0);
            String signTime = DateTimeUtil.getStringEpochSecond(data.getLong(ContractEnum.SIGN_TIME.getAttr()), DateTimeUtil.SDFDate);
            String name = getStringOrDefault(data, ContractEnum.NAME.getAttr(), "");
            String no = entityExt.getSerialNo();
            String status = contractStatusMap.getOrDefault(data.getString(ContractEnum.STATUS.getAttr()), "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            double amountDouble = data.getDoubleValue(ContractEnum.AMOUNT.getAttr());
            String amount = StringUtil.formatDouble(amountDouble);
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*-- 解释 -*/
            if (nameHide) {
                name = "";
            }
            if (linkCustomerHide) {
                customerName = "";
            }
            //经销商名称
            summaryList.add(commonHelp.setSummary(OrderEnum.LINK_DISTRIBUTOR.getAttrName(), customerName));
//            if (signTimeHide) {
//                signTime = "";
//            }
//            summaryList.add(commonHelp.setSummary(OrderEnum.SIGN_TIME.getAttrName(), signTime));
            //订单金额
            String orderAmount = data.getString(OrderEnum.AMOUNT.getAttr());
            if (amountHide) {
                orderAmount = "";
            }
            summaryList.add(commonHelp.setSummary(OrderEnum.AMOUNT.getAttrName(), orderAmount));
            //订单毛利
            Boolean grossProfitHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.GROSS_PROFIT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            String grossProfit = data.getString(OrderEnum.GROSS_PROFIT.getAttr());
            if (grossProfitHide) {
                grossProfit = "";
            }
            summaryList.add(commonHelp.setSummary(OrderEnum.GROSS_PROFIT.getAttrName(), grossProfit));
            //订单毛利率
            Boolean grossProfitRateHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ContractEnum.GROSS_PROFIT_RATE.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            Double grossProfitRate = data.getDouble(OrderEnum.GROSS_PROFIT_RATE.getAttr());
            String grossProfitRateVal = String.valueOf(grossProfitRate);
            if (grossProfitRateHide) {
                summaryList.add(commonHelp.setSummary(OrderEnum.GROSS_PROFIT_RATE.getAttrName(), ""));
            }else{
                grossProfitRateVal = attrDecimalPrecisionHelper.getNumberFormat(grossProfitRateVal, 2, null, 1);
                summaryList.add(commonHelp.setSummary(OrderEnum.GROSS_PROFIT_RATE.getAttrName(), grossProfitRateVal));
            }
            //签订人or归属人
            String belongNameStr;
            if (flag) {
                belongNameStr = cidPerforInfoMap.getOrDefault(contractId, "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION), belongNameStr));
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(ContractEnum.SIGN_PERSON.getAttr()), "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(ContractEnum.SIGN_PERSON.getAttrName(), belongNameStr));
            }
            /*-- 角标 -*/
            superScript.put("message", pushNotifyList.contains(contractId) ? 1 : 0);
            /*-- 标签 -*/
            if (statusHide) {
                status = "";
            }
            //lablesList.add(commonHelp.setLable(ContractEnum.STATUS.getAttrName(), status));
            if (noHide) {
                no = "";
            }
            titleList.add(commonHelp.setTitle(no));
            /*-- 其他（这里展示的是订单毛利） -*/
            if (amountHide) {
                amount = "";
            }
            if (Objects.equals(SystemCodeEnum.ORDER_PROFIT_RATE_DISTRIBUTOR_TABLE.getSystemCode(), systemCode)) {
                others.put("amount", grossProfitRateVal);
                others.put("isRed", isRed);
            }else{
                others.put("amount", grossProfit);
                others.put("isRed", isRed);
            }
            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的已回款业务（回款单）
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/3 18:07
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPayment(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PaymentSheetEnum enumBelongId = PaymentSheetEnum.BELONG_ID;
        PaymentSheetEnum enumPaymentId = PaymentSheetEnum.PAYMENT;
        PaymentSheetEnum enumSheetNo = PaymentSheetEnum.SHEET_NO;
        PaymentSheetEnum enumContractId = PaymentSheetEnum.CONTRACT;
        PaymentSheetEnum enumCustomerId = PaymentSheetEnum.CUSTOMER_ID;
        PaymentSheetEnum enumAmount = PaymentSheetEnum.AMOUNT;
        PaymentSheetEnum enumWriteOffAmount = PaymentSheetEnum.WRITE_OFF_AMOUNT;
        PaymentSheetEnum enumTime = PaymentSheetEnum.PAYMENT_TIME;
        PaymentSheetEnum enumPayMethod = PaymentSheetEnum.PAY_METHOD;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumSheetNo.getAttr(), enumSheetNo.getAttrName(), enumSheetNo.getFieldType()));
        if (IndicatorRuleEnum.PAYMENT_BAD == indicatorRuleEnum) {
            title.add(new TitlePojo(enumAmount.getAttr(), BadDebtEnum.BAD_DEBT_AMOUNT.getAttrName(), BadDebtEnum.BAD_DEBT_AMOUNT.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), BadDebtEnum.BAD_TIME.getAttrName(), BadDebtEnum.BAD_TIME.getFieldType()));
        } else {
            title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
            title.add(new TitlePojo(enumWriteOffAmount.getAttr(), enumWriteOffAmount.getAttrName(), enumWriteOffAmount.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
            title.add(new TitlePojo(enumPayMethod.getAttr(), enumPayMethod.getAttrName(), enumTime.getFieldType()));
        }
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName(), enumContractId.getFieldType()));
        title.add(new TitlePojo(enumPaymentId.getAttr(), BadDebtEnum.PAYMENT.getAttrName(), enumPaymentId.getFieldType()));

        //归属人ids、应收款id、合同ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<String> uuIdIn = new HashSet<>();
        Set<Long> formIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONArray belongIdArray = data.getJSONArray(enumBelongId.getAttr());
            if (belongIdArray != null) {
                userIdIn.addAll(JsonHelperUtil.parseArray(belongIdArray.toJSONString(), String.class));
            }
            String paymentIdInStr = data.getString(enumPaymentId.getAttr());
            paymentIdIn.addAll(JsonHelperUtil.parseArray(paymentIdInStr, Long.class));
            contractIdIn.addAll(JsonHelperUtil.parseArray(data.getString(enumContractId.getAttr()), Long.class));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            String uuid = entityExt.getUuid();
            uuIdIn.add(uuid);
            formIdIn.add(entityExt.getFormId());
        }
        //应收款id-应收款编号map
        PaymentEnum paymentNoEnum = PaymentEnum.PAYMENT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", paymentNoEnum.getAttr());
        Map<Long, String> paymentIdNoMap = formHelp.getFormIdAttrMapByIds4All(paymentNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAYMENT, paymentIdIn, fieldList);
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        ContractEnum contractSerialNumberEnum = ContractEnum.CONTRACT_NO;
        fieldList = Arrays.asList("id", "dataId", contractSerialNumberEnum.getAttr(), ContractEnum.getAttrConnectData(contractNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(contractNameEnum.getAttr());
        attrs.add(contractSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (openRule) {
            title.add(0, new TitlePojo(enumBelongId.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.PERFORMANCE_OWNER_PROPORTION)));
            //获取子和只有父无子的回款单信息
            List<PaasFormDataEntityExt> childNormalList = getPaymentSheetListByUUIds(corpid, uuIdIn);
            cidPerforInfoMap = formHelp.paymentSheetIdPersonInfoMap(corpid, contractIdIn, childNormalList, list);
        } else {
            title.add(0, new TitlePojo(enumBelongId.getAttr(), enumBelongId.getAttrName()));
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        //formId - 该form的支付方式
        Map<Long, Map<String, String>> formPayMethodMap = new HashMap<>(formIdIn.size());
        //回款单最多只有两个form（经销商、非经销商），方法内部层级较多，且获取方法内部使用缓存，暂不一次性获取
        for (Long formId : formIdIn) {
            //获取启用的支付方式
            Map<String, String> payMethodMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.PAYMENT_SHEET_PAY_METHOD, corpid, formId);
            formPayMethodMap.put(formId, payMethodMap);
        }
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        int refType4PaymentSheet = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long dataId = entityExt.getDataId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            //TODO 字段改动待写
            JSONArray cidArr = data.getJSONArray(enumContractId.getAttr());
            JSONArray pidArr = data.getJSONArray(enumPaymentId.getAttr());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            Long paymentSheetId = entityExt.getDataId();
            //归属人or业绩归属人
            String belongNameStr;
            if (openRule) {
                belongNameStr = cidPerforInfoMap.getOrDefault(dataId, "");
            } else {
                JSONArray uidArr = data.getJSONArray(enumBelongId.getAttr());
                belongNameStr = commonHelp.getRelationForStr(userNameMap, uidArr);
            }
            String paymentNo = commonHelp.getRelationNo(paymentIdNoMap, pidArr);
            String sheetNo = entityExt.getSerialNo();
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            Map<String, String> payMethodMap = formPayMethodMap.get(entityExt.getFormId());
            String payMethod = payMethodMap.getOrDefault(data.getString(enumPayMethod.getAttr()), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumBelongId.getAttr(), new TableDataInfoPojo(belongNameStr.toString()));
            jsonObject.put(enumPaymentId.getAttr(), new TableDataInfoPojo(paymentNo));
            jsonObject.put(enumSheetNo.getAttr(), new TableDataInfoPojo(sheetNo, 1, refType4PaymentSheet, paymentSheetId));
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(relatedContractInfo));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumWriteOffAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumWriteOffAmount.getAttr()))));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumPayMethod.getAttr(), new TableDataInfoPojo(payMethod));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的未收款业务（应收款）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/3 18:46
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPaymentUn(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PaymentEnum enumBelongId = PaymentEnum.BELONGER;
        PaymentEnum enumNo = PaymentEnum.PAYMENT_NO;
        PaymentEnum enumContractId = PaymentEnum.CONTRACT;
        PaymentEnum enumCustomerId = PaymentEnum.CUSTOMER;
        PaymentEnum enumAmount = PaymentEnum.AMOUNT;
        PaymentEnum enumUnAmount = PaymentEnum.UN_AMOUNT;
        PaymentEnum enumStatus = PaymentEnum.STATUS;
        PaymentEnum enumTime = PaymentEnum.ESTIMATE_TIME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumBelongId.getAttr(), I18nMessageUtil.getMessage(BusinessConstant.MAIN_USER)));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName(), enumContractId.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumUnAmount.getAttr(), enumUnAmount.getAttrName(), enumUnAmount.getFieldType()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        //回款计划id、合同ids、客户id
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            paymentIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            contractIdIn.add(data.getLongValue(enumContractId.getAttr()));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
        }
        List<PaasFormDataEntity> paymentTeamList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAYMENT_TEAM, corpid, paymentIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<PaymentUserEntity> teamUserList = (List<PaymentUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAYMENT_TEAM, paymentTeamList);
        //payemntId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        ContractEnum contractSerialNumberEnum = ContractEnum.CONTRACT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", contractSerialNumberEnum.getAttr(), ContractEnum.getAttrConnectData(contractNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(contractNameEnum.getAttr());
        attrs.add(contractSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        IndexTypeEnum customerIndex =  indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, customerIndex, customerIdIn, fieldList);
        int refType4Payment = XbbRefTypeEnum.PAYMENT.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long paymentId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            long contractId = data.getLongValue(enumContractId.getAttr());
            JSONArray cidArr = new JSONArray(Collections.singletonList(contractId));
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String owner = ownerNameMap.getOrDefault(paymentId, "");
            String no = entityExt.getSerialNo();
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String status = PaymentStatusEnum.getByCode(data.getString(enumStatus.getAttr())).getAlias();
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumBelongId.getAttr(), new TableDataInfoPojo(owner));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4Payment, paymentId));
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(relatedContractInfo, 1, refType4Contract,contractId));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumUnAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumUnAmount.getAttr()))));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    private ResultThroughVO formatPaymentTaskUn(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PaymentTaskEnum enumExecutor = PaymentTaskEnum.EXECUTOR;
        PaymentTaskEnum enumNo = PaymentTaskEnum.PAYMENT_TASK_NO;
        PaymentTaskEnum enumContractId = PaymentTaskEnum.LINK_CONTRACT;
        PaymentTaskEnum enumCustomerId = PaymentTaskEnum.LINK_CUSTOMER;
        PaymentTaskEnum enumAmount = PaymentTaskEnum.PAYMENT_TASK_NUM;
        PaymentTaskEnum enumStatus = PaymentTaskEnum.STATUS;
        PaymentTaskEnum enumTime = PaymentTaskEnum.EXECUTOR_TIME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumExecutor.getAttr(), enumExecutor.getAttrName()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName()));
        //应收款id、合同ids、客户id
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            paymentIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            contractIdIn.add(data.getLongValue(enumContractId.getAttr()));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
        }
        List<PaasFormDataEntity> teamUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM, corpid, paymentIdIn, null, PaasFormDataEntity.class);
        List<PaymentTaskUserEntity> userTeamEntities = (List<PaymentTaskUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM, teamUserList);
        //payemntTaskId--执行人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(userTeamEntities);
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        ContractEnum contractSerialNumberEnum = ContractEnum.CONTRACT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", contractSerialNumberEnum.getAttr(), ContractEnum.getAttrConnectData(contractNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(contractNameEnum.getAttr());
        attrs.add(contractSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        int refType4PaymentTask = XbbRefTypeEnum.PAYMENT_TASK.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long paymentTaskId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            long contractId = data.getLongValue(enumContractId.getAttr());
            JSONArray cidArr = new JSONArray(Collections.singletonList(contractId));
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String owner = ownerNameMap.getOrDefault(paymentTaskId, "");
            String no = entityExt.getSerialNo();
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String status = PaymentTaskStatusEnum.getByCode(data.getString(enumStatus.getAttr())).getAlias();
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumExecutor.getAttr(), new TableDataInfoPojo(owner));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4PaymentTask, paymentTaskId));
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(relatedContractInfo, 1, refType4Contract,contractId));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的应收款（已收款、未收款最终都展示应收款）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/13 21:28
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPayment4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PAYMENT.getCode());
        //应收款id、合同ids、客户id
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            paymentIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            contractIdIn.add(data.getLongValue(PaymentEnum.CONTRACT.getAttr()));
            customerIdIn.add(data.getLongValue(PaymentEnum.CUSTOMER.getAttr()));
        }
        List<PaasFormDataEntity> paymentTeamList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAYMENT_TEAM, corpid, paymentIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<PaymentUserEntity> teamUserList = (List<PaymentUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAYMENT_TEAM, paymentTeamList);
        //payemntId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        ContractEnum contractSerialNumberEnum = ContractEnum.CONTRACT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", contractSerialNumberEnum.getAttr(), ContractEnum.getAttrConnectData(contractNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(contractNameEnum.getAttr());
        attrs.add(contractSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long paymentId = entityExt.getId();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long contractId = data.getLong(PaymentEnum.CONTRACT.getAttr());
            JSONArray cidArr = new JSONArray(Collections.singletonList(contractId));
            Long customerId = data.getLong(PaymentEnum.CUSTOMER.getAttr());
            String owner = ownerNameMap.getOrDefault(paymentId, "");
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String statusStr = data.getString(PaymentEnum.STATUS.getAttr());
            String status = PaymentStatusEnum.getByCode(statusStr).getAlias();
            String timeStr = "";
            Long time = data.getLong(PaymentEnum.ESTIMATE_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*explains.add("关联合同：" + contractName);
            explains.add("客户名称：" + customerName);
            explains.add("负责人：" + owner);
            explains.add("预计回款日期：" + timeStr);*/
            summaryList.add(commonHelp.setSummary(PaymentEnum.CONTRACT.getAttrName(), relatedContractInfo));
            summaryList.add(commonHelp.setSummary(PaymentEnum.CUSTOMER.getAttrName(), customerName));
            summaryList.add(commonHelp.setSummary(PaymentEnum.OWNER_ID.getAttrName(), owner));
            summaryList.add(commonHelp.setSummary(PaymentEnum.ESTIMATE_TIME.getAttrName(), timeStr));

            /*-- 其他 -*/
            Double amount =data.getDoubleValue(PaymentEnum.AMOUNT.getAttr());
            Double realAmount = data.getDoubleValue(PaymentEnum.REAL_AMOUNT.getAttr());
            if (realAmount < 0) {
                amount = realAmount;
            }
            String amountStr = StringUtil.formatDouble(amount);
            Integer isRed = (Integer) data.getOrDefault(PaymentEnum.IS_RED.getAttr(), 0);
            Integer isBad = 0;
            if ( Objects.equals(PaymentStatusEnum.getByAlias(status),PaymentStatusEnum.BAD_DEBT) ){
                isBad = 1;
            }
            commonHelp.setPaymentOthers(others, amountStr, status, isRed, isBad);

            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            appListPojos.add(new AppListPojo(paymentId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的回款计划
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPaymentTask4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PAYMENT.getCode());
        //回款计划id、合同ids、客户id
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            paymentIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            contractIdIn.add(data.getLongValue(PaymentTaskEnum.LINK_CONTRACT.getAttr()));
            customerIdIn.add(data.getLongValue(PaymentTaskEnum.LINK_CUSTOMER.getAttr()));
        }
        List<PaasFormDataEntity> teamUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM, corpid, paymentIdIn, null, PaasFormDataEntity.class);
        List<PaymentTaskUserEntity> userTeamEntities = (List<PaymentTaskUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAYMENT_TASK_TEAM, teamUserList);
        //payemntId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(userTeamEntities);
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        ContractEnum contractSerialNumberEnum = ContractEnum.CONTRACT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", contractSerialNumberEnum.getAttr(), ContractEnum.getAttrConnectData(contractNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(contractNameEnum.getAttr());
        attrs.add(contractSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long paymentTaskId = entityExt.getId();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long contractId = data.getLong(PaymentTaskEnum.LINK_CONTRACT.getAttr());
            JSONArray cidArr = new JSONArray(Collections.singletonList(contractId));
            Long customerId = data.getLong(PaymentTaskEnum.LINK_CUSTOMER.getAttr());
            String owner = ownerNameMap.getOrDefault(paymentTaskId, "");
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String statusStr = data.getString(PaymentTaskEnum.STATUS.getAttr());
            String status = PaymentTaskStatusEnum.getByCode(statusStr).getAlias();
            String timeStr = "";
            Long time = data.getLong(PaymentTaskEnum.EXECUTOR_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time);
            }
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*explains.add("关联合同：" + contractName);
            explains.add("客户名称：" + customerName);
            explains.add("负责人：" + owner);
            explains.add("预计回款日期：" + timeStr);*/
            summaryList.add(commonHelp.setSummary(PaymentTaskEnum.LINK_CONTRACT.getAttrName(), relatedContractInfo));
            summaryList.add(commonHelp.setSummary(PaymentTaskEnum.LINK_CUSTOMER.getAttrName(), customerName));
            summaryList.add(commonHelp.setSummary(PaymentTaskEnum.EXECUTOR.getAttrName(), owner));
            summaryList.add(commonHelp.setSummary(PaymentTaskEnum.EXECUTOR_TIME.getAttrName(), timeStr));

            /*-- 其他 -*/
            Double amount =data.getDoubleValue(PaymentTaskEnum.PAYMENT_TASK_NUM.getAttr());
            String amountStr = StringUtil.formatDouble(amount);
            commonHelp.setPaymentOthers(others, amountStr, status, null, null);

            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            appListPojos.add(new AppListPojo(paymentTaskId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 移动端回款单穿透页
     *
     * @param corpid 公司id
     * @param list 回款单数据列表
     * @param resultThroughVo 结果
     * @param openRule 是否开启业绩分配
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @author 徐俊杰
     * @date 2019/12/11 10:09
     * @since v1.0
     */
    private ResultThroughVO formatPaymentSheet4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, boolean openRule) throws XbbException {
        PaymentSheetEnum enumContractId = PaymentSheetEnum.CONTRACT;
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<String> uuIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONArray signPerson = getJsonArrOrDefaultFromFormData(data, PaySheetEnum.BELONG_ID.getAttr(), new JSONArray());
            userIdIn.addAll(JSONArray.parseArray(signPerson.toJSONString(),String.class));
            contractIdIn.addAll(JsonHelperUtil.parseArray(data.getString(enumContractId.getAttr()), Long.class));
            uuIdIn.add(entityExt.getUuid());
        }
        //获取合同相关信息
        List<String> fieldList = Arrays.asList("id", "dataId", ContractEnum.CONTRACT_NO.getAttr(), ContractEnum.getAttrConnectData(ContractEnum.NAME));
        Set<String> attrs = new HashSet<>();
        attrs.add(ContractEnum.NAME.getAttr());
        attrs.add(ContractEnum.CONTRACT_NO.getAttr());
        Map<Long, Map<String, String>> contractIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //业绩分配
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //获取子和只有父无子的回款单信息
        List<PaasFormDataEntityExt> childNormalList = getPaymentSheetListByUUIds(corpid, uuIdIn);
        if (openRule) {
            cidPerforInfoMap = formHelp.paymentSheetIdPersonInfoMap(corpid, contractIdIn, childNormalList, list);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            Long dataId = entityExt.getDataId();
            List<FormTitlePoJo> titleList = new ArrayList<>();
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            JSONObject data = entityExt.getData();
            //客户
            String customerName = data.getString(PaymentSheetEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
            summaryList.add(commonHelp.setSummary(PaymentSheetEnum.CUSTOMER_ID.getAttrName(), customerName));
            //合同
            JSONArray cidArr = data.getJSONArray(enumContractId.getAttr());
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(contractIdAttrsMap, cidArr);
            String relatedContractInfo = getNameNumberInfo(relatedMapList, ContractEnum.NAME.getAttr(), ContractEnum.CONTRACT_NO.getAttr());
            summaryList.add(commonHelp.setSummary(PaymentSheetEnum.CONTRACT.getAttrName(), relatedContractInfo));
            //归属人
            String belongNameStr = "";
            if (openRule) {
                belongNameStr = cidPerforInfoMap.getOrDefault(dataId, "");
            } else {
                JSONArray uidArr = data.getJSONArray(PaymentSheetEnum.BELONG_ID.getAttr());
                belongNameStr = commonHelp.getRelationForStr(userNameMap, uidArr);
            }
            summaryList.add(commonHelp.setSummary(PaymentSheetEnum.BELONG_ID.getAttrName(), belongNameStr));
            //回款日期
            String timeStr = "";
            Long time = data.getLong(PaymentSheetEnum.PAYMENT_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            summaryList.add(commonHelp.setSummary(PaymentSheetEnum.PAYMENT_TIME.getAttrName(), timeStr));
            JSONObject others = disposePaymentSheetOthers(data);
            //汇总
            Long paymentSheetId = entityExt.getId();
            JSONObject superScript = new JSONObject();
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            appListPojos.add(new AppListPojo(paymentSheetId, titleList, summaryList, superScript, new ArrayList<>(), others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的联系人业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/3 19:23
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatContact(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        ContactEnum enumName = ContactEnum.NAME;
        ContactEnum enumCustomerId = ContactEnum.CUSTOMER_NAME;
        ContactEnum enumPhone = ContactEnum.PHONE;
        ContactEnum enumAddTime = ContactEnum.ADD_TIME;
        ContactEnum enumCreator = ContactEnum.CREATOR_ID;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(),enumName.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        title.add(new TitlePojo(enumPhone.getAttr(), enumPhone.getAttrName(), enumPhone.getFieldType()));
        title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
        title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
        //创建人id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        int refTypeContact = XbbRefTypeEnum.CONTACT.getCode();
        int refTypeCustomer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long contactId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), ""));
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            JSONArray phoneJsonArray = data.getJSONArray(enumPhone.getAttr());
            String phone = commonHelp.formatPhone(phoneJsonArray);
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refTypeContact, contactId));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refTypeCustomer, customerId));
            jsonObject.put(enumPhone.getAttr(), new TableDataInfoPojo(phone));
            jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
            jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端格式化穿透后的联系人业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/14 17:12
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatContact4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.CONTACT.getCode());
        //创建人id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            userIdIn.add(entityExt.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(ContactEnum.CUSTOMER_NAME.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long contactId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(ContactEnum.CUSTOMER_NAME.getAttr());
            String name = String.valueOf(data.getOrDefault(ContactEnum.NAME.getAttr(), ""));
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            /*-- 解释 -*/
            /*explains.add("创建人：" + creator);
            explains.add(customerName);*/
            summaryList.add(commonHelp.setSummary(ContactEnum.CREATOR_ID.getAttrName(), creator));
            summaryList.add(commonHelp.setSummary(ContactEnum.CUSTOMER_NAME.getAttrName(), customerName));

            /*-- 标签 -*/
            Integer importantDegree = (Integer) data.getOrDefault(ContactEnum.IMPORTANT_DEGREE.getAttr(), 0);
            StarEnum importantDegree1 = StarEnum.getStarByValue(importantDegree);
            String importantDegreeStr = importantDegree1.getText();
            //JsonHelperUtil.addToJSONArray(tags, importantDegreeStr);
            lablesList.add(commonHelp.setLable(ContactEnum.IMPORTANT_DEGREE.getAttrName(), importantDegreeStr));

            titleList.add(commonHelp.setTitle(name));

            /*-- 其他 -*/
            JSONArray phoneJsonArray = data.getJSONArray(ContactEnum.PHONE.getAttr());
            commonHelp.setContactPhone(others, phoneJsonArray, false, 1, entityExt, data);
            appListPojos.add(new AppListPojo(contactId, titleList, summaryList, superScript, lablesList, others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的发票业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/3 19:53
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatInvoice(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        InvoiceEnum enumApplyUser = InvoiceEnum.APPLY_USER;
        InvoiceEnum enumNo = InvoiceEnum.SHEET_NO;
        InvoiceEnum enumName = InvoiceEnum.INVOICE_NUMBER;
        InvoiceEnum enumCustomerId = InvoiceEnum.CUSTOMER_NAME;
        InvoiceEnum enumContractId = InvoiceEnum.CONTRACT_ID;
        InvoiceEnum enumAmount = InvoiceEnum.TOTAL_MONEY;
        InvoiceEnum enumType = InvoiceEnum.INVOICE_TYPE;
        InvoiceEnum enumTime = InvoiceEnum.INVOICE_DATE;
        InvoiceEnum enumPaymentType = InvoiceEnum.PAYMENT_RELATIONSHIP;
        InvoiceEnum enumPaymentId = InvoiceEnum.PAYMENT_ID;
        InvoiceEnum enumPaymentSheet = InvoiceEnum.PAYMENT_SHEET_ID;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumApplyUser.getAttr(), enumApplyUser.getAttrName(), enumApplyUser.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumType.getAttr(), enumType.getAttrName(), enumType.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName(), enumContractId.getFieldType()));
        title.add(new TitlePojo(enumPaymentType.getAttr(), enumPaymentType.getAttrName(), enumPaymentType.getFieldType()));
        title.add(new TitlePojo(enumPaymentId.getAttr(), enumPaymentId.getAttrName(), enumPaymentId.getFieldType()));
        title.add(new TitlePojo(enumPaymentSheet.getAttr(), enumPaymentSheet.getAttrName(), enumPaymentSheet.getFieldType()));
        //申请人ids、客户id、合同ids、回款计划id、回款单id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> paymentIdIn = new HashSet<>();
        Set<Long> paymentSheetIdIn = new HashSet<>();
        Set<Long> formIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(entityExt.getOwnerId());
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            JSONArray cidArr = data.getJSONArray(enumContractId.getAttr());
            if (cidArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(cidArr.toString(), Long.class);
                contractIdIn.addAll(idIn);
            }
            JSONArray pidArr = data.getJSONArray(enumPaymentId.getAttr());
            if (pidArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(pidArr.toString(), Long.class);
                paymentIdIn.addAll(idIn);
            }
            JSONArray psidArr = data.getJSONArray(enumPaymentSheet.getAttr());
            if (psidArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(psidArr.toString(), Long.class);
                paymentSheetIdIn.addAll(idIn);
            }
            formIdIn.add(entityExt.getFormId());
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //应收款id-应收款编号map
        PaymentEnum paymentNoEnum = PaymentEnum.PAYMENT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", paymentNoEnum.getAttr());
        Map<Long, String> paymentIdNoMap = formHelp.getFormIdAttrMapByIds4All(paymentNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAYMENT, paymentIdIn, fieldList);
        //应收款id-应收款编号map
        PaymentSheetEnum paymentSheetNoEnum = PaymentSheetEnum.SHEET_NO;
        fieldList = Arrays.asList("id", "dataId", paymentSheetNoEnum.getAttr());
        Map<Long, String> paymentSheetIdNoMap = formHelp.getFormIdAttrMapByIds4All(paymentSheetNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET, paymentSheetIdIn, fieldList);
        //合同id-合同编号map
        ContractEnum contractNoEnum = ContractEnum.CONTRACT_NO;
        fieldList = Arrays.asList("id", "dataId", contractNoEnum.getAttr());
        Map<Long, String> contractIdNoMap = formHelp.getFormIdAttrMapByIds4All(contractNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //formId - 该form的发票类型
        Map<Long, Map<String, String>> formInvoiceTypeMap = new HashMap<>(formIdIn.size());
        //回款单最多只有两个form（经销商、非经销商），方法内部层级较多，且获取方法内部使用缓存，暂不一次性获取
        for (Long formId : formIdIn) {
            //获取启用的发票类型
            Map<String, String> invoiceTypeMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.INVOICE_TYPE, corpid, formId);
            formInvoiceTypeMap.put(formId, invoiceTypeMap);
        }
        int refType4Invoice = XbbRefTypeEnum.INVOICE.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long invoiceId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            //发票关联的是多个合同id、多个回款id
            JSONArray cidArr = data.getJSONArray(enumContractId.getAttr());
            JSONArray pidArr = data.getJSONArray(enumPaymentId.getAttr());
            JSONArray psidArr = data.getJSONArray(enumPaymentSheet.getAttr());
            String applyUser = userNameMap.getOrDefault(entityExt.getOwnerId(), "");
            String no = entityExt.getSerialNo();
            String name = data.getString(enumName.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String contractNo = commonHelp.getRelationNo(contractIdNoMap, cidArr);
            String paymentNo = commonHelp.getRelationNo(paymentIdNoMap, pidArr);
            String paymentSheetNo = commonHelp.getRelationNo(paymentSheetIdNoMap, psidArr);
            Map<String, String> invoiceTypeMap = formInvoiceTypeMap.get(entityExt.getFormId());
            String invoiceType = invoiceTypeMap.getOrDefault(data.getString(enumType.getAttr()), "");
            String paymentTypeCode = data.getString(enumPaymentType.getAttr());
            String paymentType = "";
            if (paymentTypeCode != null) {
                paymentType = I18nMessageUtil.getMessage(PaymentRelationshipEnum.getByCode(paymentTypeCode).getAlias());
            }
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumApplyUser.getAttr(), new TableDataInfoPojo(applyUser));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4Invoice, invoiceId));
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name));
            jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(contractNo));
            jsonObject.put(enumPaymentId.getAttr(), new TableDataInfoPojo(paymentNo));
            jsonObject.put(enumPaymentSheet.getAttr(), new TableDataInfoPojo(paymentSheetNo));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(invoiceType));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumPaymentType.getAttr(), new TableDataInfoPojo(paymentType));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的发票业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 11:21
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatInvoice4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.INVOICE.getCode());
        //申请人ids、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> originIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(entityExt.getOwnerId());
            customerIdIn.add(data.getLongValue(InvoiceEnum.CUSTOMER_NAME.getAttr()));
            originIdIn.add(data.getLongValue(InvoiceEnum.ORIGIN_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //原始发票id--原始发票编号
        InvoiceEnum enumSheetNo = InvoiceEnum.SHEET_NO;
        fieldList = Arrays.asList("id", enumSheetNo.getAttr());
        Map<Long, String> originIdAndSheetNoMap = formHelp.getFormIdAttrMapByIds4All(enumSheetNo.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_INVOICE, originIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long invoiceId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long customerId = data.getLongValue(InvoiceEnum.CUSTOMER_NAME.getAttr());
            String applyUser = userNameMap.getOrDefault(entityExt.getOwnerId(), "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            JSONArray customerInvoiceArr = data.getJSONArray(InvoiceEnum.CUSTOMER_INVOICE.getAttr());
            String title = commonHelp.getInvoiceTitle(customerInvoiceArr);
            // 解释
            summaryList.add(commonHelp.setSummary(InvoiceEnum.APPLY_USER.getAttrName(), applyUser));
            summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(InvoiceConstant.TITLE), title));
            summaryList.add(commonHelp.setSummary(InvoiceEnum.CUSTOMER_NAME.getAttrName(), customerName));
            //红冲发票关联原始发票
            Long originId = data.getLongValue(InvoiceEnum.ORIGIN_ID.getAttr());
            if (originIdAndSheetNoMap.containsKey(originId)) {
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.ORIGIN_INVOICE), originIdAndSheetNoMap.getOrDefault(originId, "")));
            }
            Long time = data.getLongValue(InvoiceEnum.INVOICE_DATE.getAttr());
            summaryList.add(commonHelp.setSummary(InvoiceEnum.INVOICE_DATE.getAttrName(), DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate)));
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));

            commonHelp.setInvoiceInfo(data, superScript, others);
            appListPojos.add(new AppListPojo(invoiceId, titleList, summaryList, superScript, new ArrayList<>(), others,entityExt.getAppId(), entityExt.getMenuId(), entityExt.getFormId()));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的进项发票业务
     *
     * @param corpid 公司id
     * @param list 列表数据
     * @param resultThroughVo 穿透显示数据
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2020/3/16 15:42
     * @since v1.0
     */
    private ResultThroughVO formatInvoicePurchase(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PurchaseInvoiceEnum enumApplyUser = PurchaseInvoiceEnum.APPLY_USER;
        PurchaseInvoiceEnum enumNo = PurchaseInvoiceEnum.SHEET_NO;
        PurchaseInvoiceEnum enumName = PurchaseInvoiceEnum.INVOICE_NUMBER;
        PurchaseInvoiceEnum enumSupplierId = PurchaseInvoiceEnum.SUPPLIER_NAME;
        PurchaseInvoiceEnum enumPurchaseId = PurchaseInvoiceEnum.PURCHASE_ID;
        PurchaseInvoiceEnum enumAmount = PurchaseInvoiceEnum.TOTAL_MONEY;
        PurchaseInvoiceEnum enumType = PurchaseInvoiceEnum.INVOICE_TYPE;
        PurchaseInvoiceEnum enumTime = PurchaseInvoiceEnum.INVOICE_DATE;
        PurchaseInvoiceEnum enumPayType = PurchaseInvoiceEnum.PAY_RELATIONSHIP;
        PurchaseInvoiceEnum enumPayPlanId = PurchaseInvoiceEnum.PAY_PLAN_ID;
        PurchaseInvoiceEnum enumPaySheet = PurchaseInvoiceEnum.PAY_SHEET_ID;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumApplyUser.getAttr(), enumApplyUser.getAttrName(), enumApplyUser.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumType.getAttr(), enumType.getAttrName(), enumType.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        title.add(new TitlePojo(enumSupplierId.getAttr(), enumSupplierId.getAttrName(), enumSupplierId.getFieldType()));
        title.add(new TitlePojo(enumPurchaseId.getAttr(), enumPurchaseId.getAttrName(), enumPurchaseId.getFieldType()));
        title.add(new TitlePojo(enumPayType.getAttr(), enumPayType.getAttrName(), enumPayType.getFieldType()));
        title.add(new TitlePojo(enumPayPlanId.getAttr(), enumPayPlanId.getAttrName(), enumPayPlanId.getFieldType()));
        title.add(new TitlePojo(enumPaySheet.getAttr(), enumPaySheet.getAttrName(), enumPaySheet.getFieldType()));
        //申请人ids、供应商id、采购合同ids、付款计划id、付款单id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        Set<Long> purchaseIdIn = new HashSet<>();
        Set<Long> payPlanIdIn = new HashSet<>();
        Set<Long> paySheetIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(entityExt.getOwnerId());
            supplierIdIn.add(data.getLongValue(enumSupplierId.getAttr()));
            JSONArray puridArr = data.getJSONArray(enumPurchaseId.getAttr());
            if (puridArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(puridArr.toString(), Long.class);
                purchaseIdIn.addAll(idIn);
            }
            JSONArray payPlanidArr = data.getJSONArray(enumPayPlanId.getAttr());
            if (payPlanidArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(payPlanidArr.toString(), Long.class);
                payPlanIdIn.addAll(idIn);
            }
            JSONArray psidArr = data.getJSONArray(enumPaySheet.getAttr());
            if (psidArr != null) {
                List<Long> idIn = JsonHelperUtil.parseArray(psidArr.toString(), Long.class);
                paySheetIdIn.addAll(idIn);
            }
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //付款计划id-付款计划编号map
        PayPlanEnum payPlanNoEnum = PayPlanEnum.PAY_PLAN_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", payPlanNoEnum.getAttr());
        Map<Long, String> payPlanIdNoMap = formHelp.getFormIdAttrMapByIds4All(payPlanNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAY_PLAN, payPlanIdIn, fieldList);
        //付款单id-付款单编号map
        PaySheetEnum paySheetNoEnum = PaySheetEnum.PAY_PLAN_NO;
        fieldList = Arrays.asList("id", "dataId", paySheetNoEnum.getAttr());
        Map<Long, String> paySheetIdNoMap = formHelp.getFormIdAttrMapByIds4All(paySheetNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET, paySheetIdIn, fieldList);
        //采购合同id-采购合同编号map
        PurchaseEnum purchaseNoEnum = PurchaseEnum.SHEET_NO;
        fieldList = Arrays.asList("id", "dataId", purchaseNoEnum.getAttr());
        Map<Long, String> purchaseIdNoMap = formHelp.getFormIdAttrMapByIds4All(purchaseNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseIdIn, fieldList);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //查询出发票的表单id
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的发票类型
        //todo 现在缺进项发票
        Map<String, String> invoiceTypeMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.INVOICE_TYPE, corpid, formId);
        int refType4InvoicePurchase = XbbRefTypeEnum.PURCHASE_INVOICE.getCode();
        int refType4Supplier = XbbRefTypeEnum.SUPPLIER.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long invoiceId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long supplierId = data.getLong(enumSupplierId.getAttr());
            //发票关联的是多个合同id、多个回款id
            JSONArray puridArr = data.getJSONArray(enumPurchaseId.getAttr());
            JSONArray payPlanidArr = data.getJSONArray(enumPayPlanId.getAttr());
            JSONArray psidArr = data.getJSONArray(enumPaySheet.getAttr());
            String applyUser = userNameMap.getOrDefault(entityExt.getOwnerId(), "");
            String no = entityExt.getSerialNo();
            String name = data.getString(enumName.getAttr());
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            String purchaseNo = commonHelp.getRelationNo(purchaseIdNoMap, puridArr);
            String payPlanNo = commonHelp.getRelationNo(payPlanIdNoMap, payPlanidArr);
            String paySheetNo = commonHelp.getRelationNo(paySheetIdNoMap, psidArr);
            String invoiceType = invoiceTypeMap.getOrDefault(data.getString(enumType.getAttr()), "");
            String payTypeCode = data.getString(enumPayType.getAttr());
            String payType = "";
            if (payTypeCode != null) {
                payType = I18nMessageUtil.getMessage(PayRelationshipEnum.getByCode(payTypeCode).getAlias());
            }
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumApplyUser.getAttr(), new TableDataInfoPojo(applyUser));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4InvoicePurchase, invoiceId));
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name));
            jsonObject.put(enumSupplierId.getAttr(), new TableDataInfoPojo(supplierName, 1, refType4Supplier, supplierId));
            jsonObject.put(enumPurchaseId.getAttr(), new TableDataInfoPojo(purchaseNo));
            jsonObject.put(enumPayPlanId.getAttr(), new TableDataInfoPojo(payPlanNo));
            jsonObject.put(enumPaySheet.getAttr(), new TableDataInfoPojo(paySheetNo));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumType.getAttr(), new TableDataInfoPojo(invoiceType));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumPayType.getAttr(), new TableDataInfoPojo(payType));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的进项发票业务-app
     *
     * @param corpid 公司id
     * @param list 列表数据
     * @param resultThroughVo 穿透显示数据
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2020/3/16 15:43
     * @since v1.0
     */
    private ResultThroughVO formatInvoicePurchase4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
        //申请人ids、供应商id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        Set<Long> originIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(entityExt.getOwnerId());
            supplierIdIn.add(data.getLongValue(PurchaseInvoiceEnum.SUPPLIER_NAME.getAttr()));
            originIdIn.add(data.getLongValue(PurchaseInvoiceEnum.ORIGIN_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        List<String> fieldList = Arrays.asList("id", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //原始发票id--原始发票编号
        PurchaseInvoiceEnum enumSheetNo = PurchaseInvoiceEnum.SHEET_NO;
        fieldList = Arrays.asList("id", enumSheetNo.getAttr());
        Map<Long, String> originIdAndSheetNoMap = formHelp.getFormIdAttrMapByIds4All(enumSheetNo.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PURCHASE_INVOICE, originIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long invoiceId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long supplierId = data.getLongValue(PurchaseInvoiceEnum.SUPPLIER_NAME.getAttr());
            String applyUser = userNameMap.getOrDefault(entityExt.getOwnerId(), "");
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            JSONArray supplierInvoiceArr = data.getJSONArray(PurchaseInvoiceEnum.CUSTOMER_INVOICE.getAttr());
            String title = commonHelp.getInvoiceTitle(supplierInvoiceArr);
            // 解释
            summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(PurchaseInvoiceEnum.APPLY_USER.getAttrName()), applyUser));
            summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(InvoiceConstant.TITLE), title));
            summaryList.add(commonHelp.setSummary(PurchaseInvoiceEnum.SUPPLIER_NAME.getAttrName(), supplierName));
            //红冲发票关联原始发票
            Long originId = data.getLongValue(PurchaseInvoiceEnum.ORIGIN_ID.getAttr());
            if (originIdAndSheetNoMap.containsKey(originId)) {
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.ORIGIN_INVOICE), originIdAndSheetNoMap.getOrDefault(originId, "")));
            }
            Long time = data.getLongValue(InvoiceEnum.INVOICE_DATE.getAttr());
            summaryList.add(commonHelp.setSummary(PurchaseInvoiceEnum.INVOICE_DATE.getAttrName(), DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate)));
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));

            commonHelp.setInvoicePurchaseInfo(data, superScript, others);
            appListPojos.add(new AppListPojo(invoiceId, titleList, summaryList, superScript, new ArrayList<>(), others,entityExt.getAppId(), entityExt.getMenuId(), entityExt.getFormId()));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的销售产品业务（最终展示的数据是根据合同产品表得到，即传入的list为ContractProductEntity合集）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 14:19
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductContract(String corpid, List<ContractProductEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        //暂时用产品实体的枚举ProductEnum来标识合同销售产品穿透后字段的key（其中合同id和销量字段分别用SUPPLIER、STOCK对应的字段名标识）
        ProductEnum enumName = ProductEnum.NAME;
        ProductEnum enumNo = ProductEnum.PRODUCT_NO;
        ProductEnum enumContractId = ProductEnum.SUPPLIER;
        ProductEnum enumSpecification = ProductEnum.SPECIFICATION_LINK_TEXT;
        ProductEnum enumUnit = ProductEnum.UNIT;
        ProductEnum enumNum = ProductEnum.STOCK;
        ProductEnum enumPrice = ProductEnum.PRICE;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumContractId.getAttr(), ContractEnum.CONTRACT_NO.getAttrName(), enumContractId.getFieldType()));
        //规格展示列名用ProductEnum.SPECIFICATION字段，获取字段值用ProductEnum.SPECIFICATION_LINK_TEXT
        title.add(new TitlePojo(enumSpecification.getAttr(), ProductEnum.SPECIFICATION.getAttrName(), enumSpecification.getFieldType()));
        title.add(new TitlePojo(enumUnit.getAttr(), enumUnit.getAttrName(), enumUnit.getFieldType()));
        title.add(new TitlePojo(enumNum.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.SALE_NUM), enumNum.getFieldType()));
        title.add(new TitlePojo(enumPrice.getAttr(), enumPrice.getAttrName(), enumPrice.getFieldType()));
        //产品ids、合同ids
        Set<Long> productIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        for (ContractProductEntity entity : list) {
            productIdIn.add(entity.getProductId());
            contractIdIn.add(entity.getContractId());
        }
        List<PaasFormDataEntityExt> productList = formHelp.getFormListByIds4All(corpid, IndexTypeEnum.IDX_SAAS_PRODUCT, productIdIn, null);
        //产品id--产品实体
        Map<Long, PaasFormDataEntityExt> idProductMap = formHelp.getMap4IdEntity(productList);
        //父产品ids
        Set<Long> parentIdIn = new HashSet<>();
        String parentIdAttr = ProductEnum.PARENT_ID.getAttr();
        for (PaasFormDataEntityExt entityExt : productList) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            parentIdIn.add(data.getLong(parentIdAttr));
        }
        //父级产品id--产品编号map
        Map<Long, String> parentIdNoMap = formHelp.getParentIdNoMap(corpid, parentIdIn);
        //合同id-合同编号map
        ContractEnum contractNoEnum = ContractEnum.CONTRACT_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", contractNoEnum.getAttr());
        Map<Long, String> contractIdNoMap = formHelp.getFormIdAttrMapByIds4All(contractNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //获取启用的产品单位
        Map<String, String> unitMap = formHelp.getProductUnitItemMap(corpid);
        int refType4Product = XbbRefTypeEnum.PRODUCT.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (ContractProductEntity entity : list) {
            Long productId = entity.getProductId();
            Long contractId = entity.getContractId();
            PaasFormDataEntityExt product = idProductMap.getOrDefault(productId, new PaasFormDataEntityExt());
            JSONObject data = JsonHelperUtil.getJSONObject(product.getData());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), entity.getProductName()));
            String no = formHelp.getProductNo(parentIdNoMap, data);
            String contractNo = contractIdNoMap.getOrDefault(contractId, "");
            String specification = specificationModel.joinSpecification(data.getString(enumSpecification.getAttr()));
            //产品单位处理
            String unit = unitMap.getOrDefault(data.getString(enumUnit.getAttr()), "");
            String productNum = entity.getProductNum() == null ? "0" : StringUtil.formatDouble(entity.getProductNum());
            String priceStr = "";
            Double price = entity.getPrice();
            if (price != null && price >= 0) {
                priceStr = StringUtil.formatDouble(price);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType4Product, productId));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no));
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(contractNo, 1, refType4Contract, contractId));
            jsonObject.put(enumSpecification.getAttr(), new TableDataInfoPojo(specification));
            jsonObject.put(enumUnit.getAttr(), new TableDataInfoPojo(unit));
            jsonObject.put(enumNum.getAttr(), new TableDataInfoPojo(productNum));
            jsonObject.put(enumPrice.getAttr(), new TableDataInfoPojo(priceStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的订单产品
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/1/15 14:19
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductOrder(String corpid, List<ContractProductEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        //暂时用产品实体的枚举ProductEnum来标识合同销售产品穿透后字段的key（其中合同id和销量字段分别用SUPPLIER、STOCK对应的字段名标识）
        ProductEnum enumName = ProductEnum.NAME;
        ProductEnum enumNo = ProductEnum.PRODUCT_NO;
        ProductEnum enumContractId = ProductEnum.SUPPLIER;
        OrderEnum enumOrderDistributor = OrderEnum.LINK_CUSTOMER_HIDE;//关联经销商
        OrderEnum enumOrderSignTime = OrderEnum.SIGN_TIME;//下单日期
        ProductEnum enumSpecification = ProductEnum.SPECIFICATION_LINK_TEXT;
        ProductEnum enumUnit = ProductEnum.UNIT;
        ProductEnum enumNum = ProductEnum.STOCK;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumContractId.getAttr(), OrderEnum.ORDER_NO.getAttrName()));
        title.add(new TitlePojo(enumOrderDistributor.getAttr(), OrderEnum.LINK_DISTRIBUTOR.getAttrName()));
        title.add(new TitlePojo(enumOrderSignTime.getAttr(), enumOrderSignTime.getAttrName()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName()));
        //规格展示列名用ProductEnum.SPECIFICATION字段，获取字段值用ProductEnum.SPECIFICATION_LINK_TEXT
        title.add(new TitlePojo(enumSpecification.getAttr(), ProductEnum.SPECIFICATION.getAttrName()));
        title.add(new TitlePojo(enumUnit.getAttr(), enumUnit.getAttrName()));
        title.add(new TitlePojo(enumNum.getAttr(), ContractProductEnum.NUM.getAttrName()));
        //产品ids、合同ids
        Set<Long> productIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        //遍历数据把订单idList查出来，再去数据库查询订单集合

        for (ContractProductEntity entity : list) {
            productIdIn.add(entity.getProductId());
            contractIdIn.add(entity.getContractId());
        }
        List<PaasFormDataEntityExt> productList = formHelp.getFormListByIds4All(corpid, IndexTypeEnum.IDX_SAAS_PRODUCT, productIdIn, null);
        //产品id--产品实体
        Map<Long, PaasFormDataEntityExt> idProductMap = formHelp.getMap4IdEntity(productList);
        //父产品ids
        Set<Long> parentIdIn = new HashSet<>();
        String parentIdAttr = ProductEnum.PARENT_ID.getAttr();
        for (PaasFormDataEntityExt entityExt : productList) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            parentIdIn.add(data.getLong(parentIdAttr));
        }
        //父级产品id--产品编号map
        Map<Long, String> parentIdNoMap = formHelp.getParentIdNoMap(corpid, parentIdIn);
        //合同id-合同编号map
        OrderEnum orderNoEnum = OrderEnum.ORDER_NO;
        OrderEnum orderDistributorEnum = OrderEnum.LINK_CUSTOMER_HIDE;
        List<String> fieldList = Arrays.asList("id", "dataId", orderNoEnum.getAttr(), OrderEnum.getAttrConnectData(enumOrderDistributor),
                OrderEnum.getAttrConnectData(OrderEnum.LINK_DISTRIBUTOR), OrderEnum.getAttrConnectData(enumOrderSignTime));
        //formId 要查出来
        List<Long> orderFormIdList = paasFormModel.getFormIdList4Distributor(XbbRefTypeEnum.CONTRACT.getCode(), corpid, 1);
        Map<Long, JSONObject> orderIdMap = formHelp.getOrderDataByIds4Distributor(orderFormIdList, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //获取启用的产品单位
        Map<String, String> unitMap = formHelp.getProductUnitItemMap(corpid);
        int refType4Product = XbbRefTypeEnum.PRODUCT.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (ContractProductEntity entity : list) {
            Long productId = entity.getProductId();
            Long contractId = entity.getContractId();
            PaasFormDataEntityExt product = idProductMap.getOrDefault(productId, new PaasFormDataEntityExt());
            JSONObject data = JsonHelperUtil.getJSONObject(product.getData());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), entity.getProductName()));
            String no = formHelp.getProductNo(parentIdNoMap, data);
            JSONObject contractMap = orderIdMap.get(contractId);
            String contractNo = (String) contractMap.getOrDefault("orderNo","");
            String orderDistributor = (String) contractMap.getOrDefault("distributorName","");
            Long time = contractMap.getLong("signTime");
            String orderSignTime = "";
            if (time != null && time > 0) {
                orderSignTime = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String specification = specificationModel.joinSpecification(data.getString(enumSpecification.getAttr()));
            //产品单位处理
            String unit = unitMap.getOrDefault(data.getString(enumUnit.getAttr()), "");
            String productNum = entity.getProductNum() == null ? "0" : StringUtil.formatDouble(entity.getProductNum());
            String priceStr = "";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(contractNo, 1, refType4Contract, contractId));
            jsonObject.put(enumOrderDistributor.getAttr(), new TableDataInfoPojo(orderDistributor, 1, refType4Contract, contractId));
            //下单日期
            jsonObject.put(enumOrderSignTime.getAttr(), new TableDataInfoPojo(String.valueOf(orderSignTime)));
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType4Product, productId));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no));
            jsonObject.put(enumSpecification.getAttr(), new TableDataInfoPojo(specification));
            jsonObject.put(enumUnit.getAttr(), new TableDataInfoPojo(unit));
            jsonObject.put(enumNum.getAttr(), new TableDataInfoPojo(productNum));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的订单产品(APP)
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/1/15 14:19
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductOrder4App(String corpid, List<ContractProductEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        //暂时用产品实体的枚举ProductEnum来标识合同销售产品穿透后字段的key（其中合同id和销量字段分别用SUPPLIER、STOCK对应的字段名标识）
        ProductEnum enumName = ProductEnum.NAME;
        ProductEnum enumNo = ProductEnum.PRODUCT_NO;
        ProductEnum enumContractId = ProductEnum.SUPPLIER;
        OrderEnum enumOrderDistributor = OrderEnum.LINK_CUSTOMER_HIDE;//关联经销商
        OrderEnum enumOrderSignTime = OrderEnum.SIGN_TIME;//下单日期
        ProductEnum enumSpecification = ProductEnum.SPECIFICATION_LINK_TEXT;
        ProductEnum enumUnit = ProductEnum.UNIT;
        ProductEnum enumNum = ProductEnum.STOCK;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumContractId.getAttr(), OrderEnum.ORDER_NO.getAttrName()));
        title.add(new TitlePojo(enumOrderDistributor.getAttr(), OrderEnum.LINK_DISTRIBUTOR.getAttrName()));
        title.add(new TitlePojo(enumOrderSignTime.getAttr(), enumOrderSignTime.getAttrName()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName()));
        //规格展示列名用ProductEnum.SPECIFICATION字段，获取字段值用ProductEnum.SPECIFICATION_LINK_TEXT
        title.add(new TitlePojo(enumSpecification.getAttr(), ProductEnum.SPECIFICATION.getAttrName()));
        title.add(new TitlePojo(enumUnit.getAttr(), enumUnit.getAttrName()));
        title.add(new TitlePojo(enumNum.getAttr(), ContractProductEnum.NUM.getAttrName()));
        //产品ids、合同ids
        Set<Long> productIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        //遍历数据把订单idList查出来，再去数据库查询订单集合

        for (ContractProductEntity entity : list) {
            productIdIn.add(entity.getProductId());
            contractIdIn.add(entity.getContractId());
        }
        List<PaasFormDataEntityExt> productList = formHelp.getFormListByIds4All(corpid, IndexTypeEnum.IDX_SAAS_PRODUCT, productIdIn, null);
        //产品id--产品实体
        Map<Long, PaasFormDataEntityExt> idProductMap = formHelp.getMap4IdEntity(productList);
        //父产品ids
        Set<Long> parentIdIn = new HashSet<>();
        String parentIdAttr = ProductEnum.PARENT_ID.getAttr();
        for (PaasFormDataEntityExt entityExt : productList) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            parentIdIn.add(data.getLong(parentIdAttr));
        }
        //父级产品id--产品编号map
        Map<Long, String> parentIdNoMap = formHelp.getParentIdNoMap(corpid, parentIdIn);
        //合同id-合同编号map
        OrderEnum orderNoEnum = OrderEnum.ORDER_NO;
        OrderEnum orderDistributorEnum = OrderEnum.LINK_CUSTOMER_HIDE;
        List<String> fieldList = Arrays.asList("id", "dataId", orderNoEnum.getAttr(), OrderEnum.getAttrConnectData(enumOrderDistributor),
                OrderEnum.getAttrConnectData(OrderEnum.LINK_DISTRIBUTOR), OrderEnum.getAttrConnectData(enumOrderSignTime));
        //formId 要查出来
        List<Long> orderFormIdList = paasFormModel.getFormIdList4Distributor(XbbRefTypeEnum.CONTRACT.getCode(), corpid, 1);
        Map<Long, JSONObject> orderIdMap = formHelp.getOrderDataByIds4Distributor(orderFormIdList, corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //获取启用的产品单位
        Map<String, String> unitMap = formHelp.getProductUnitItemMap(corpid);
        int refType4Product = XbbRefTypeEnum.PRODUCT.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (ContractProductEntity entity : list) {

            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();
            Map<String, Object> param = new HashMap<>(16);
            param.put("corpid", corpid);
            param.put("saasMark", 1);
            param.put("alias", "product");
            param.put("del", 0);
            param.put("enable", 1);
            List<PaasAppEntity> enableApps = paasAppModel.list(param);
            Long appId = enableApps.get(0).getId();

            Long menuId = 7084L;
            Long formId = entity.getFormId();

            Long productId = entity.getProductId();
            Long contractId = entity.getContractId();
            PaasFormDataEntityExt product = idProductMap.getOrDefault(productId, new PaasFormDataEntityExt());
            JSONObject data = JsonHelperUtil.getJSONObject(product.getData());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), entity.getProductName()));
            String no = formHelp.getProductNo(parentIdNoMap, data);
            JSONObject contractMap = orderIdMap.get(contractId);
            String contractNo = (String) contractMap.getOrDefault("orderNo","");
            String orderDistributor = (String) contractMap.getOrDefault("distributorName","");
            Long time = contractMap.getLong("signTime");
            String orderSignTime = "";
            if (time != null && time > 0) {
                orderSignTime = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String specification = specificationModel.joinSpecification(data.getString(enumSpecification.getAttr()));
            //产品单位处理
            String unit = unitMap.getOrDefault(data.getString(enumUnit.getAttr()), "");
            String productNum = entity.getProductNum() == null ? "0" : StringUtil.formatDouble(entity.getProductNum());
            String priceStr = "";
            JSONObject jsonObject = new JSONObject();

            summaryList.add(commonHelp.setSummary(enumContractId.getAttr(), contractNo));
            summaryList.add(commonHelp.setSummary(enumOrderDistributor.getAttr(), orderDistributor));
            summaryList.add(commonHelp.setSummary(enumOrderSignTime.getAttr(), String.valueOf(orderSignTime)));
            summaryList.add(commonHelp.setSummary(enumName.getAttr(), name));
            summaryList.add(commonHelp.setSummary(enumNo.getAttr(), no));
            summaryList.add(commonHelp.setSummary(enumSpecification.getAttr(), specification));
            summaryList.add(commonHelp.setSummary(enumUnit.getAttr(), unit));
            summaryList.add(commonHelp.setSummary(enumNum.getAttr(), productNum));
//            jsonObject.put(enumContractId.getAttr(), new TableDataInfoPojo(contractNo, 1, refType4Contract, contractId));
//            jsonObject.put(enumOrderDistributor.getAttr(), new TableDataInfoPojo(orderDistributor, 1, refType4Contract, contractId));
//            //下单日期
//            jsonObject.put(enumOrderSignTime.getAttr(), new TableDataInfoPojo(String.valueOf(orderSignTime)));
//            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType4Product, productId));
//            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no));
//            jsonObject.put(enumSpecification.getAttr(), new TableDataInfoPojo(specification));
//            jsonObject.put(enumUnit.getAttr(), new TableDataInfoPojo(unit));
//            jsonObject.put(enumNum.getAttr(), new TableDataInfoPojo(productNum));
//            resultData.add(jsonObject);
//            lablesList.add(commonHelp.setLable(ContractEnum.STATUS.getAttrName(), status));
//            if (noHide) {
//                no = "";
//            }
//            titleList.add(commonHelp.setTitle(no));
            JSONObject others = new JSONObject();
//                others.put("amount", amount);
//            others.put("isRed", isRed);
            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, null, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }


    /**
     * 格式化穿透后的退货单产品
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/1/15 14:19
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductReturn(String corpid, List<ContractProductEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        ReturnEnum enumReturnNo= ReturnEnum.RETURN_NO;//退货单编号 searialNo
        ReturnEnum enumReturnName = ReturnEnum.RETURN_NAME;//退货单名称text_3
        ReturnEnum enumLinkDistributor = ReturnEnum.LINK_DISTRIBUTOR_LINKED_TEXT;//关联经销商 text_9
        ReturnEnum enumLinkOrder = ReturnEnum.ORDER_ID_LINKED_TEXT;//关联订货单 text_10
        ReturnEnum enumSignDate = ReturnEnum.SIGN_DATE;//签订日期 date_1
        ContractProductSubFormEnum enumProductNo = ContractProductSubFormEnum.PRODUCT_NO;//产品编号text_24
        ContractProductSubFormEnum enumProductName = ContractProductSubFormEnum.PRODUCT_NAME;//产品名称text_23
        ContractProductSubFormEnum enumProductSpec = ContractProductSubFormEnum.SPECIFICATION;//规格text_26
        ContractProductSubFormEnum enumProductUnit = ContractProductSubFormEnum.PRODUCT_UNIT;//单位text_25
        ContractProductSubFormEnum enumProductNum = ContractProductSubFormEnum.PRODUCT_NUM;//数量num_32

        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumReturnNo.getAttr(), enumReturnNo.getAttrName()));
        title.add(new TitlePojo(enumReturnName.getAttr(), enumReturnName.getAttrName()));
        title.add(new TitlePojo(enumLinkDistributor.getAttr(), ReturnEnum.LINK_DISTRIBUTOR.getAttrName()));
        title.add(new TitlePojo(enumLinkOrder.getAttr(), ReturnEnum.ORDER_ID.getAttrName()));
        title.add(new TitlePojo(enumSignDate.getAttr(), enumSignDate.getAttrName()));
        title.add(new TitlePojo(enumProductNo.getDataAttr(), ProductEnum.PRODUCT_NO.getAttrName()));
        title.add(new TitlePojo(enumProductName.getDataAttr(), ProductEnum.NAME.getAttrName()));
        title.add(new TitlePojo(enumProductSpec.getDataAttr(), ProductEnum.SPECIFICATION.getAttrName()));
        title.add(new TitlePojo(enumProductUnit.getDataAttr(), ProductEnum.UNIT.getAttrName()));
        title.add(new TitlePojo(enumProductNum.getDataAttr(), SelectProductEnum.NUM.getAttrName()));

        //产品ids、合同ids
        Set<Long> productIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        //遍历数据把订单idList查出来，再去es查询订单集合
        for (ContractProductEntity entity : list) {
            productIdIn.add(entity.getProductId());
            contractIdIn.add(entity.getContractId());
        }
        List<PaasFormDataEntityExt> productList = formHelp.getFormListByIds4All(corpid, IndexTypeEnum.IDX_SAAS_PRODUCT, productIdIn, null);
        //产品id--产品实体
        Map<Long, PaasFormDataEntityExt> idProductMap = formHelp.getMap4IdEntity(productList);
        //父产品ids
        Set<Long> parentIdIn = new HashSet<>();
        String parentIdAttr = ProductEnum.PARENT_ID.getAttr();
        for (PaasFormDataEntityExt entityExt : productList) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            parentIdIn.add(data.getLong(parentIdAttr));
        }
        //父级产品id--产品编号map
        Map<Long, String> parentIdNoMap = formHelp.getParentIdNoMap(corpid, parentIdIn);
        //合同id-合同编号map
        OrderEnum orderNoEnum = OrderEnum.ORDER_NO;
        OrderEnum orderDistributorEnum = OrderEnum.LINK_CUSTOMER_HIDE;
        // 退货单编号、退货单名称、关联经销商、关联订货单、签订日期
        List<String> fieldList = Arrays.asList("id", "dataId", enumReturnNo.getAttr(), ReturnEnum.getAttrConnectData(enumReturnName),
                ReturnEnum.getAttrConnectData(enumLinkDistributor), ReturnEnum.getAttrConnectData(enumLinkOrder),
                ReturnEnum.getAttrConnectData(enumSignDate), ReturnEnum.getAttrConnectData(ReturnEnum.LINK_DISTRIBUTOR),
                ReturnEnum.getAttrConnectData(ReturnEnum.ORDER_ID), ReturnEnum.getAttrConnectData(ReturnEnum.RED_CONTRACT_ID));
        //formId 要查出来
        List<Long> returnFormIdList = paasFormModel.getFormIdList4Distributor(XbbRefTypeEnum.REFUND.getCode(), corpid, 1);
        Map<Long, JSONObject> redContractIdMap = formHelp.getReturnDataByIds4Distributor(returnFormIdList, corpid, IndexTypeEnum.IDX_SAAS_REFUND, contractIdIn, fieldList);
        //获取启用的产品单位
        Map<String, String> unitMap = formHelp.getProductUnitItemMap(corpid);
        int refType4Return = XbbRefTypeEnum.REFUND.getCode();
        int refType4Distributor = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        int refType4Order = XbbRefTypeEnum.CONTRACT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (ContractProductEntity entity : list) {
            Long productId = entity.getProductId(); //产品id
            Long contractId = entity.getContractId();//红冲合同id
            JSONObject returnData = redContractIdMap.get(contractId);
            if (returnData == null){
                continue;
            }
            String returnNo = returnData.getString("returnNo");
            String returnName = returnData.getString("returnName");
            String linkDistributor = returnData.getString("linkDistributor");
            Long linkDistributorId = returnData.getLong("linkDistributorId");//经销商id
            String linkOrder = returnData.getString("linkOrder");
            Long time = returnData.getLong("signDate");
            String signDate = "";
            if (time != null && time > 0) {
                signDate = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            Long orderId = returnData.getLong("orderId");//订货单ID
            Long returnId = returnData.getLong("dataId");//退货单id
            //先封装退货单编号、退货单名称、关联经销商、关联订货单、签订日期。
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumReturnNo.getAttr(), new TableDataInfoPojo(returnNo, 1, refType4Return, returnId));
            jsonObject.put(enumReturnName.getAttr(), new TableDataInfoPojo(returnName, 1, refType4Return, returnId));
            jsonObject.put(enumLinkDistributor.getAttr(), new TableDataInfoPojo(linkDistributor, 1, refType4Distributor, linkDistributorId));
            jsonObject.put(enumLinkOrder.getAttr(), new TableDataInfoPojo(linkOrder, 1, refType4Order, orderId));
            jsonObject.put(enumSignDate.getAttr(), new TableDataInfoPojo(signDate));

            PaasFormDataEntityExt product = idProductMap.getOrDefault(productId, new PaasFormDataEntityExt());
            JSONObject data = JsonHelperUtil.getJSONObject(product.getData());
            String name = String.valueOf(data.getOrDefault(enumProductName.getDataAttr(), entity.getProductName()));
            String no = formHelp.getProductNo(parentIdNoMap, data);
            String specification = String.valueOf(data.getOrDefault(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr(), ""));
            try {
                JSONObject specObject = JSON.parseObject(specification);
                if (specObject == null) {
                    jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(specification));
                }else{
                    StringBuilder stringBuilder = new StringBuilder();
                    StringUtil.stringBuilderAppendSuffix(stringBuilder,"/",specObject.values().toArray());
                    jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(stringBuilder.toString()));
                }
            } catch (JSONException e) {
                jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(specification));
            }
            //产品单位处理
            String unit = unitMap.getOrDefault(data.getString(ProductEnum.UNIT.getAttr()), "");
            String productNum = entity.getProductNum() == null ? "0" : StringUtil.formatDouble(Math.abs(entity.getProductNum()));
            String priceStr = "";
            Double price = entity.getPrice();
            if (price != null && price >= 0) {
                priceStr = StringUtil.formatDouble(price);
            }
            jsonObject.put(enumProductNo.getDataAttr(), new TableDataInfoPojo(no));
            jsonObject.put(enumProductName.getDataAttr(), new TableDataInfoPojo(name));
            jsonObject.put(enumProductUnit.getDataAttr(), new TableDataInfoPojo(unit));
            jsonObject.put(enumProductNum.getDataAttr(), new TableDataInfoPojo(productNum));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的退货单产品(APP)
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2021/1/15 14:19
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductReturn4App(String corpid, List<ContractProductEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        ReturnEnum enumReturnNo= ReturnEnum.RETURN_NO;//退货单编号 searialNo
        ReturnEnum enumReturnName = ReturnEnum.RETURN_NAME;//退货单名称text_3
        ReturnEnum enumLinkDistributor = ReturnEnum.LINK_DISTRIBUTOR_LINKED_TEXT;//关联经销商 text_9
        ReturnEnum enumLinkOrder = ReturnEnum.ORDER_ID_LINKED_TEXT;//关联订货单 text_10
        ReturnEnum enumSignDate = ReturnEnum.SIGN_DATE;//签订日期 date_1
        ContractProductSubFormEnum enumProductNo = ContractProductSubFormEnum.PRODUCT_NO;//产品编号text_24
        ContractProductSubFormEnum enumProductName = ContractProductSubFormEnum.PRODUCT_NAME;//产品名称text_23
        ContractProductSubFormEnum enumProductSpec = ContractProductSubFormEnum.SPECIFICATION;//规格text_26
        ContractProductSubFormEnum enumProductUnit = ContractProductSubFormEnum.PRODUCT_UNIT;//单位text_25
        ContractProductSubFormEnum enumProductNum = ContractProductSubFormEnum.PRODUCT_NUM;//数量num_32

        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumReturnNo.getAttr(), enumReturnNo.getAttrName()));
        title.add(new TitlePojo(enumReturnName.getAttr(), enumReturnName.getAttrName()));
        title.add(new TitlePojo(enumLinkDistributor.getAttr(), ReturnEnum.LINK_DISTRIBUTOR.getAttrName()));
        title.add(new TitlePojo(enumLinkOrder.getAttr(), ReturnEnum.ORDER_ID.getAttrName()));
        title.add(new TitlePojo(enumSignDate.getAttr(), enumSignDate.getAttrName()));
        title.add(new TitlePojo(enumProductNo.getDataAttr(), ProductEnum.PRODUCT_NO.getAttrName()));
        title.add(new TitlePojo(enumProductName.getDataAttr(), ProductEnum.NAME.getAttrName()));
        title.add(new TitlePojo(enumProductSpec.getDataAttr(), ProductEnum.SPECIFICATION.getAttrName()));
        title.add(new TitlePojo(enumProductUnit.getDataAttr(), ProductEnum.UNIT.getAttrName()));
        title.add(new TitlePojo(enumProductNum.getDataAttr(), SelectProductEnum.NUM.getAttrName()));

        //产品ids、合同ids
        Set<Long> productIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        //遍历数据把订单idList查出来，再去es查询订单集合
        for (ContractProductEntity entity : list) {
            productIdIn.add(entity.getProductId());
            contractIdIn.add(entity.getContractId());
        }
        List<PaasFormDataEntityExt> productList = formHelp.getFormListByIds4All(corpid, IndexTypeEnum.IDX_SAAS_PRODUCT, productIdIn, null);
        //产品id--产品实体
        Map<Long, PaasFormDataEntityExt> idProductMap = formHelp.getMap4IdEntity(productList);
        //父产品ids
        Set<Long> parentIdIn = new HashSet<>();
        String parentIdAttr = ProductEnum.PARENT_ID.getAttr();
        for (PaasFormDataEntityExt entityExt : productList) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            parentIdIn.add(data.getLong(parentIdAttr));
        }
        //父级产品id--产品编号map
        Map<Long, String> parentIdNoMap = formHelp.getParentIdNoMap(corpid, parentIdIn);
        //合同id-合同编号map
        OrderEnum orderNoEnum = OrderEnum.ORDER_NO;
        OrderEnum orderDistributorEnum = OrderEnum.LINK_CUSTOMER_HIDE;
        // 退货单编号、退货单名称、关联经销商、关联订货单、签订日期
        List<String> fieldList = Arrays.asList("id", "dataId", enumReturnNo.getAttr(), ReturnEnum.getAttrConnectData(enumReturnName),
                ReturnEnum.getAttrConnectData(enumLinkDistributor), ReturnEnum.getAttrConnectData(enumLinkOrder),
                ReturnEnum.getAttrConnectData(enumSignDate), ReturnEnum.getAttrConnectData(ReturnEnum.LINK_DISTRIBUTOR),
                ReturnEnum.getAttrConnectData(ReturnEnum.ORDER_ID), ReturnEnum.getAttrConnectData(ReturnEnum.RED_CONTRACT_ID));
        //formId 要查出来
        List<Long> returnFormIdList = paasFormModel.getFormIdList4Distributor(XbbRefTypeEnum.REFUND.getCode(), corpid, 1);
        Map<Long, JSONObject> redContractIdMap = formHelp.getReturnDataByIds4Distributor(returnFormIdList, corpid, IndexTypeEnum.IDX_SAAS_REFUND, contractIdIn, fieldList);
        //获取启用的产品单位
        Map<String, String> unitMap = formHelp.getProductUnitItemMap(corpid);
        int refType4Return = XbbRefTypeEnum.REFUND.getCode();
        int refType4Distributor = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        int refType4Order = XbbRefTypeEnum.CONTRACT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (ContractProductEntity entity : list) {
            Long productId = entity.getProductId(); //产品id
            Long contractId = entity.getContractId();//红冲合同id
            JSONObject returnData = redContractIdMap.get(contractId);
            if (returnData == null){
                continue;
            }
            String returnNo = returnData.getString("returnNo");
            String returnName = returnData.getString("returnName");
            String linkDistributor = returnData.getString("linkDistributor");
            Long linkDistributorId = returnData.getLong("linkDistributorId");//经销商id
            String linkOrder = returnData.getString("linkOrder");
            Long time = returnData.getLong("signDate");
            String signDate = "";
            if (time != null && time > 0) {
                signDate = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            Long orderId = returnData.getLong("orderId");//订货单ID
            Long returnId = returnData.getLong("dataId");//退货单id
            //先封装退货单编号、退货单名称、关联经销商、关联订货单、签订日期。
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumReturnNo.getAttr(), new TableDataInfoPojo(returnNo, 1, refType4Return, returnId));
            jsonObject.put(enumReturnName.getAttr(), new TableDataInfoPojo(returnName, 1, refType4Return, returnId));
            jsonObject.put(enumLinkDistributor.getAttr(), new TableDataInfoPojo(linkDistributor, 1, refType4Distributor, linkDistributorId));
            jsonObject.put(enumLinkOrder.getAttr(), new TableDataInfoPojo(linkOrder, 1, refType4Order, orderId));
            jsonObject.put(enumSignDate.getAttr(), new TableDataInfoPojo(signDate));

            PaasFormDataEntityExt product = idProductMap.getOrDefault(productId, new PaasFormDataEntityExt());
            JSONObject data = JsonHelperUtil.getJSONObject(product.getData());
            String name = String.valueOf(data.getOrDefault(enumProductName.getDataAttr(), entity.getProductName()));
            String no = formHelp.getProductNo(parentIdNoMap, data);
            String specification = String.valueOf(data.getOrDefault(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr(), ""));
            try {
                JSONObject specObject = JSON.parseObject(specification);
                if (specObject == null) {
                    jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(specification));
                }else{
                    StringBuilder stringBuilder = new StringBuilder();
                    StringUtil.stringBuilderAppendSuffix(stringBuilder,"/",specObject.values().toArray());
                    jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(stringBuilder.toString()));
                }
            } catch (JSONException e) {
                jsonObject.put(enumProductSpec.getDataAttr(), new TableDataInfoPojo(specification));
            }
            //产品单位处理
            String unit = unitMap.getOrDefault(data.getString(ProductEnum.UNIT.getAttr()), "");
            String productNum = entity.getProductNum() == null ? "0" : StringUtil.formatDouble(Math.abs(entity.getProductNum()));
            String priceStr = "";
            Double price = entity.getPrice();
            if (price != null && price >= 0) {
                priceStr = StringUtil.formatDouble(price);
            }
            jsonObject.put(enumProductNo.getDataAttr(), new TableDataInfoPojo(no));
            jsonObject.put(enumProductName.getDataAttr(), new TableDataInfoPojo(name));
            jsonObject.put(enumProductUnit.getDataAttr(), new TableDataInfoPojo(unit));
            jsonObject.put(enumProductNum.getDataAttr(), new TableDataInfoPojo(productNum));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }
    /**
     * 格式化穿透后的退货退款业务（通过红冲合同id查询退货退款）
     * @param indicatorRuleEnum 统计指标类型
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 16:30
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatRefund(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        RefundEnum enumName = RefundEnum.REFUND_NAME;
        RefundEnum enumNo = RefundEnum.REFUND_NO;
        RefundEnum enumAmount = RefundEnum.RETURN_AMOUNT;
        RefundEnum enumRefundReason = RefundEnum.REFUND_REASON;
        RefundEnum enumContractId = RefundEnum.CONTRACT_ID;
        RefundEnum enumCustomerId = RefundEnum.CUSTOMER_ID;
        RefundEnum enumSignPerson = RefundEnum.SIGN_USER;
        RefundEnum enumTime = RefundEnum.SIGN_DATE;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumRefundReason.getAttr(), enumRefundReason.getAttrName(), enumRefundReason.getFieldType()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName(), enumContractId.getFieldType()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName(), enumCustomerId.getFieldType()));
        //签订人ids、合同ids、红冲合同ids（通过红冲和ids去查业绩分配）、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> redContractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> refundIds = new HashSet<>();
        RefundEnum enumRedContractId = RefundEnum.RED_CONTRACT_ID;
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            contractIdIn.add(data.getLongValue(enumContractId.getAttr()));
            redContractIdIn.add(data.getLongValue(enumRedContractId.getAttr()));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            refundIds.add(entityExt.getId());
        }
        //合同id-名称map
        ContractEnum contractNameEnum = ContractEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", ContractEnum.getAttrConnectData(contractNameEnum));
        Map<Long, String> contractIdNameMap = formHelp.getFormIdAttrMapByIds4All(contractNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且红冲金额统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum == IndicatorRuleEnum.RED_CONTRACT;
        if (flag) {
            title.add(new TitlePojo(enumSignPerson.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION)));
            //退货退款的业绩分配是与红冲合同挂钩的，因此要用红冲合同id进行查询，读取时也要用红冲合同id
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, redContractIdIn);
        } else {
            title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName()));
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName()));
        //查询出退货退款的表单id
        //TODO getByBusinessType
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.REFUND.getCode(), corpid);
        //退货formId
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的退货原因
        Map<String, String> refundReasonMap = RefundReasonEnum.refundReasonMap();
        int refType4Refund = XbbRefTypeEnum.REFUND.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();

        PaasFormExplainEntity byFormId = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(byFormId)) {
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        Map<String, FieldAttrEntity> fieldAttrEntityMap = ExplainUtil.getExplainMap(byFormId.getExplains());

        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(refundIds, corpid, XbbRefTypeEnum.REFUND.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        Boolean reasonHide;
        Boolean linkContractHide;
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long refundId = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(refundId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(refundId, new ArrayList<>()));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumAmount.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumCustomerId.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkContractHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumContractId.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumTime.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumSignPerson.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumName.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumNo.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            reasonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumRefundReason.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long contractId = data.getLong(enumContractId.getAttr());
            Long redContractId = data.getLong(enumRedContractId.getAttr());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), ""));
            String no = entityExt.getSerialNo();
            String refundReason = refundReasonMap.getOrDefault(data.getString(enumRefundReason.getAttr()), "");
            String contractName = contractIdNameMap.getOrDefault(contractId, "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String amount = StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()));
            //签订人or分配人
            String signPersonStr;
            if (flag) {
                //用红冲合同id读取分配人
                signPersonStr = cidPerforInfoMap.getOrDefault(redContractId, "");
            } else {
                signPersonStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), "");
            }
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            if (amountHide) {
                amount = "";
            }
            if (reasonHide) {
                refundReason = "";
            }
            if (signPersonHide) {
                signPersonStr = "";
            }
            if (signTimeHide) {
                timeStr = "";
            }
            TableDataInfoPojo refundNoData = new TableDataInfoPojo(no, 1, refType4Refund, refundId);
            if (noHide) {
                refundNoData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo refundNameData = new TableDataInfoPojo(name, 1, refType4Refund, refundId);
            if (nameHide) {
                refundNameData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo customerData = new TableDataInfoPojo(customerName, 1, refType4Customer, customerId);
            if (linkCustomerHide) {
                customerData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo contractData = new TableDataInfoPojo(contractName, 1, refType4Contract, contractId);
            if (linkContractHide) {
                contractData = new TableDataInfoPojo("");
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), refundNameData);
            jsonObject.put(enumNo.getAttr(), refundNoData);
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(amount));
            jsonObject.put(enumRefundReason.getAttr(), new TableDataInfoPojo(refundReason));
            jsonObject.put(enumContractId.getAttr(), contractData);
            jsonObject.put(enumCustomerId.getAttr(), customerData);
            jsonObject.put(enumSignPerson.getAttr(), new TableDataInfoPojo(signPersonStr));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的退货单业务
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @param resultThroughDTO 穿透DTO
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author weiming
     * @date 2020/1/14 17:27
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatReturn(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {

        ReturnEnum enumName = ReturnEnum.RETURN_NAME;
        ReturnEnum enumNo = ReturnEnum.RETURN_NO;
        ReturnEnum enumAmount = ReturnEnum.RETURN_AMOUNT;
        ReturnEnum enumRefundReason = ReturnEnum.REFUND_REASON;
        ReturnEnum enumContractId = ReturnEnum.ORDER_ID;
        ReturnEnum enumCustomerId = ReturnEnum.LINK_DISTRIBUTOR;
        ReturnEnum enumSignPerson = ReturnEnum.SIGN_USER;
        ReturnEnum enumTime = ReturnEnum.SIGN_DATE;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName()));
        title.add(new TitlePojo(enumRefundReason.getAttr(), enumRefundReason.getAttrName()));
        title.add(new TitlePojo(enumContractId.getAttr(), enumContractId.getAttrName()));
        title.add(new TitlePojo(enumCustomerId.getAttr(), enumCustomerId.getAttrName()));
        //签订人ids、合同ids、红冲合同ids（通过红冲和ids去查业绩分配）、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> contractIdIn = new HashSet<>();
        Set<Long> redContractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> refundIds = new HashSet<>();
        RefundEnum enumRedContractId = RefundEnum.RED_CONTRACT_ID;
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            contractIdIn.add(data.getLongValue(enumContractId.getAttr()));
            redContractIdIn.add(data.getLongValue(enumRedContractId.getAttr()));
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            refundIds.add(entityExt.getId());
        }
        //合同id-名称map
        List<String> fieldList = Arrays.asList("id", "dataId", "serialNo");
        Map<Long, String> contractIdNameMap = formHelp.getFormIdAttrMapByIds4All(OrderEnum.ORDER_NO.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_CONTRACT, contractIdIn, fieldList);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且红冲金额统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum == IndicatorRuleEnum.RED_CONTRACT;
        if (flag) {
            title.add(new TitlePojo(enumSignPerson.getAttr(), I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION)));
            //退货退款的业绩分配是与红冲合同挂钩的，因此要用红冲合同id进行查询，读取时也要用红冲合同id
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, redContractIdIn);
        } else {
            title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName()));
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName()));
        //查询出退货退款的表单id
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType4Distributor(XbbRefTypeEnum.REFUND.getCode(), corpid,1,null);
        //退货formId
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的退货原因
        Map<String, String> refundReasonMap = RefundReasonEnum.refundReasonMap();
        int refType4Refund = XbbRefTypeEnum.REFUND.getCode();
        int refType4Contract = XbbRefTypeEnum.CONTRACT.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();

        PaasFormExplainEntity byFormId = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(byFormId)) {
            throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
        }
        Map<String, FieldAttrEntity> fieldAttrEntityMap = ExplainUtil.getExplainMap(byFormId.getExplains());

        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(refundIds, corpid, XbbRefTypeEnum.REFUND.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        Boolean reasonHide;
        Boolean linkContractHide;
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long refundId = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(refundId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(refundId, new ArrayList<>()));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumAmount.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumCustomerId.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkContractHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumContractId.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumTime.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumSignPerson.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumName.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumNo.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            reasonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(enumRefundReason.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long contractId = data.getLong(enumContractId.getAttr());
            Long redContractId = data.getLong(enumRedContractId.getAttr());
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), ""));
            String no = entityExt.getSerialNo();
            String refundReason = refundReasonMap.getOrDefault(data.getString(enumRefundReason.getAttr()), "");
            String contractName = contractIdNameMap.getOrDefault(contractId, "");
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String amount = StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()));
            //签订人or分配人
            String signPersonStr;
            if (flag) {
                //用红冲合同id读取分配人
                signPersonStr = cidPerforInfoMap.getOrDefault(redContractId, "");
            } else {
                signPersonStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), "");
            }
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            if (amountHide) {
                amount = "";
            }
            if (reasonHide) {
                refundReason = "";
            }
            if (signPersonHide) {
                signPersonStr = "";
            }
            if (signTimeHide) {
                timeStr = "";
            }
            TableDataInfoPojo refundNoData = new TableDataInfoPojo(no, 1, refType4Refund, refundId);
            if (noHide) {
                refundNoData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo refundNameData = new TableDataInfoPojo(name, 1, refType4Refund, refundId);
            if (nameHide) {
                refundNameData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo customerData = new TableDataInfoPojo(customerName, 1, refType4Customer, customerId);
            if (linkCustomerHide) {
                customerData = new TableDataInfoPojo("");
            }
            TableDataInfoPojo contractData = new TableDataInfoPojo(contractName, 1, refType4Contract, contractId);
            if (linkContractHide) {
                contractData = new TableDataInfoPojo("");
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), refundNameData);
            jsonObject.put(enumNo.getAttr(), refundNoData);
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(amount));
            jsonObject.put(enumRefundReason.getAttr(), new TableDataInfoPojo(refundReason));
            jsonObject.put(enumContractId.getAttr(), contractData);
            jsonObject.put(enumCustomerId.getAttr(), customerData);
            jsonObject.put(enumSignPerson.getAttr(), new TableDataInfoPojo(signPersonStr));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的退货退款业务（通过红冲合同id查询退货退款，只有红冲需要考虑业绩分配）
     * @param indicatorRuleEnum 统计指标类型
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 20:33
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatRefund4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.REFUND.getCode());
        //签订人ids、合同ids、红冲合同ids（通过红冲和ids去查业绩分配）、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> redContractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> refundIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(RefundEnum.SIGN_USER.getAttr()));
            redContractIdIn.add(data.getLongValue(RefundEnum.RED_CONTRACT_ID.getAttr()));
            customerIdIn.add(data.getLongValue(RefundEnum.CUSTOMER_ID.getAttr()));
            refundIds.add(entityExt.getId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且红冲金额统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum == IndicatorRuleEnum.RED_CONTRACT;
        if (flag) {
            //退货退款的业绩分配是与红冲合同挂钩的，因此要用红冲合同id进行查询，读取时也要用红冲合同id
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, redContractIdIn);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }

        Map<String, FieldAttrEntity> fieldAttrEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(list)) {
            Long formId = list.get(0).getFormId();
            PaasFormExplainEntity byFormId = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(byFormId)) {
                throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
            }
            fieldAttrEntityMap = ExplainUtil.getExplainMap(byFormId.getExplains());
        }
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(refundIds, corpid, XbbRefTypeEnum.REFUND.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long refundId = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(refundId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(refundId, new ArrayList<>()));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.RETURN_AMOUNT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.CUSTOMER_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.SIGN_DATE.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.SIGN_USER.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.REFUND_NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.REFUND_NO.getAttr(), new FieldAttrEntity()), handlerExplainDTO);


            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long redContractId = data.getLong(RefundEnum.RED_CONTRACT_ID.getAttr());
            Long customerId = data.getLong(RefundEnum.CUSTOMER_ID.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String refundNo = entityExt.getSerialNo();

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();


            //commonHelp.setRefundInfo(entityExt, data, customerName, belongNameStr, explains, others);
            //其他
            if (noHide) {
                refundNo = "";
            }
            others.put("serialNo", refundNo);
            // 退货金额
            String amount = StringUtil.formatDouble(data.getDoubleValue(RefundEnum.RETURN_AMOUNT.getAttr()));
            if (amountHide) {
                amount = "";
            }
            others.put("amount", amount);

            // 退货退款合同名称
            String name = String.valueOf(data.getOrDefault(RefundEnum.REFUND_NAME.getAttr(), ""));
            if (nameHide) {
                name = "";
            }
            summaryList.add(commonHelp.setSummary(ContractEnum.NAME.getAttrName() + ":", name));
            //签订人or分配人
            String belongNameStr;
            if (flag) {
                //用红冲合同id读取分配人
                belongNameStr = cidPerforInfoMap.getOrDefault(redContractId, "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION) , belongNameStr));
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(RefundEnum.SIGN_USER.getAttr()), "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(RefundEnum.SIGN_USER.getAttrName(), belongNameStr));
            }

            Long time = data.getLongValue(RefundEnum.SIGN_DATE.getAttr());
            String signTimeStr = time == 0L ? "" : DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            if (signTimeHide) {
                signTimeStr = "";
            }
            if (linkCustomerHide) {
                customerName = "";
            }
            summaryList.add(commonHelp.setSummary(RefundEnum.SIGN_DATE.getAttrName(), signTimeStr));
            summaryList.add(commonHelp.setSummary(RefundEnum.CUSTOMER_ID.getAttrName(), customerName));

            titleList.add(commonHelp.setTitle(refundNo));

            appListPojos.add(new AppListPojo(refundId, titleList, summaryList, superScript, new ArrayList<>(), others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的退货退款业务（通过红冲合同id查询退货退款，只有红冲需要考虑业绩分配）
     * @param indicatorRuleEnum 统计指标类型
     * @param corpid 公司id
     * @param openRule 是否开启业绩分配
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 20:33
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatReturn4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, boolean openRule, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo, ResultThroughDTO resultThroughDTO) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.REFUND.getCode());
        //签订人ids、合同ids、红冲合同ids（通过红冲和ids去查业绩分配）、客户id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> redContractIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        Set<Long> refundIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(RefundEnum.SIGN_USER.getAttr()));
            redContractIdIn.add(data.getLongValue(RefundEnum.RED_CONTRACT_ID.getAttr()));
            customerIdIn.add(data.getLongValue(RefundEnum.CUSTOMER_ID.getAttr()));
            refundIds.add(entityExt.getId());
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //合同id -- 下属内该合同分配的业绩实体合集
        Map<Long, String> cidPerforInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //员工id--员工名称
        Map<String, String> userNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //开启业绩分配，且红冲金额统计时，才会读取业绩分配人
        boolean flag = openRule && indicatorRuleEnum == IndicatorRuleEnum.RED_CONTRACT;
        if (flag) {
            //退货退款的业绩分配是与红冲合同挂钩的，因此要用红冲合同id进行查询，读取时也要用红冲合同id
            cidPerforInfoMap = formHelp.getCidPerforInfoMap(corpid, redContractIdIn);
        } else {
            userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        }

        Map<String, FieldAttrEntity> fieldAttrEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(list)) {
            Long formId = list.get(0).getFormId();
            PaasFormExplainEntity byFormId = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(byFormId)) {
                throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012);
            }
            fieldAttrEntityMap = ExplainUtil.getExplainMap(byFormId.getExplains());
        }
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamHelp.setUserIdMap(refundIds, corpid, XbbRefTypeEnum.REFUND.getCode(), false, mainUserMap, coUserMap);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(resultThroughDTO, handlerExplainDTO);
        Boolean amountHide;
        Boolean linkCustomerHide;
        Boolean signTimeHide;
        Boolean signPersonHide;
        Boolean nameHide;
        Boolean noHide;
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long refundId = entityExt.getId();

            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(refundId, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(refundId, new ArrayList<>()));
            amountHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.RETURN_AMOUNT.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            linkCustomerHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.CUSTOMER_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.SIGN_DATE.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            signPersonHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.SIGN_USER.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            nameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.REFUND_NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
            noHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(RefundEnum.REFUND_NO.getAttr(), new FieldAttrEntity()), handlerExplainDTO);


            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long redContractId = data.getLong(RefundEnum.RED_CONTRACT_ID.getAttr());
            String linkContract = data.getString(RefundEnum.CONTRACT_ID_LINKED_TEXT.getAttr());
            Long customerId = data.getLong(RefundEnum.CUSTOMER_ID.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String refundNo = entityExt.getSerialNo();

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();


            //commonHelp.setRefundInfo(entityExt, data, customerName, belongNameStr, explains, others);
            //其他
            if (noHide) {
                refundNo = "";
            }
            others.put("serialNo", refundNo);
            // 退货金额
            String amount = StringUtil.formatDouble(data.getDoubleValue(RefundEnum.RETURN_AMOUNT.getAttr()));
            if (amountHide) {
                amount = "";
            }
            others.put("amount", amount);

            // 退货退款合同名称
            String name = String.valueOf(data.getOrDefault(RefundEnum.REFUND_NAME.getAttr(), ""));
            if (nameHide) {
                name = "";
            }
            //summaryList.add(commonHelp.setSummary(ContractEnum.NAME.getAttrName() + ":", name));
            //关联订货单
            summaryList.add(commonHelp.setSummary(ReturnEnum.ORDER_ID.getAttrName() + ":", linkContract));
            //签订人or分配人
            String belongNameStr;
            if (flag) {
                //用红冲合同id读取分配人
                belongNameStr = cidPerforInfoMap.getOrDefault(redContractId, "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(I18nMessageUtil.getMessage(I18nStringConstant.OWNER_PROPORTION) , belongNameStr));
            } else {
                belongNameStr = userNameMap.getOrDefault(data.getString(RefundEnum.SIGN_USER.getAttr()), "");
                if (signPersonHide) {
                    belongNameStr = "";
                }
                summaryList.add(commonHelp.setSummary(RefundEnum.SIGN_USER.getAttrName(), belongNameStr));
            }

            Long time = data.getLongValue(RefundEnum.SIGN_DATE.getAttr());
            String signTimeStr = time == 0L ? "" : DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            if (signTimeHide) {
                signTimeStr = "";
            }
            if (linkCustomerHide) {
                customerName = "";
            }
            //summaryList.add(commonHelp.setSummary(RefundEnum.SIGN_DATE.getAttrName(), signTimeStr));
            summaryList.add(commonHelp.setSummary(ReturnEnum.LINK_DISTRIBUTOR.getAttrName(), customerName));

            titleList.add(commonHelp.setTitle(refundNo));

            appListPojos.add(new AppListPojo(refundId, titleList, summaryList, superScript, new ArrayList<>(), others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的已付款业务（回款单）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 17:11
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPayPlan(IndicatorRuleEnum indicatorRuleEnum, String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PaySheetEnum enumBelongId = PaySheetEnum.BELONG_ID;
        PaySheetEnum enumPayPlan = PaySheetEnum.PAY_PLAN;
        PaySheetEnum enumSheetNo = PaySheetEnum.PAY_PLAN_NO;
        PaySheetEnum enumPurchaseId = PaySheetEnum.LINK_PURCHASE;
        PaySheetEnum enumSupplierId = PaySheetEnum.LINK_SUPPLIER;
        PaySheetEnum enumAmount = PaySheetEnum.AMOUNT;
        PaySheetEnum enumWriteOffAmount = PaySheetEnum.WRITE_OFF_AMOUNT;
        PaySheetEnum enumTime = PaySheetEnum.REAL_PAY_TIME;
        PaySheetEnum enumPayType = PaySheetEnum.PAY_TYPE;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumBelongId.getAttr(), enumBelongId.getAttrName(), enumBelongId.getFieldType()));
        title.add(new TitlePojo(enumSheetNo.getAttr(), enumSheetNo.getAttrName(), enumSheetNo.getFieldType()));
        if (IndicatorRuleEnum.PAY_BAD == indicatorRuleEnum) {
            title.add(new TitlePojo(enumAmount.getAttr(), BadDebtEnum.BAD_DEBT_AMOUNT.getAttrName(), enumAmount.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), BadDebtEnum.BAD_TIME.getAttrName(), enumTime.getFieldType()));
        } else {
            title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
            title.add(new TitlePojo(enumWriteOffAmount.getAttr(), enumWriteOffAmount.getAttrName(), enumWriteOffAmount.getFieldType()));
            title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
            title.add(new TitlePojo(enumPayType.getAttr(), enumPayType.getAttrName(), enumPayType.getFieldType()));
        }
        title.add(new TitlePojo(enumSupplierId.getAttr(), enumSupplierId.getAttrName(), enumSupplierId.getFieldType()));
        title.add(new TitlePojo(enumPurchaseId.getAttr(), enumPurchaseId.getAttrName(), enumPurchaseId.getFieldType()));
        title.add(new TitlePojo(enumPayPlan.getAttr(), enumPayPlan.getAttrName(), enumPayType.getFieldType()));
        //归属人ids、付款计划id、采购合同ids、供应商id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> payPlanIdIn = new HashSet<>();
        Set<Long> purchaseIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONArray belongIdArray = data.getJSONArray(enumBelongId.getAttr());
            if (belongIdArray != null) {
                userIdIn.addAll(JsonHelperUtil.parseArray(belongIdArray.toJSONString(), String.class));
            }
            String payPlanIdInStr = data.getString(enumPayPlan.getAttr());
            payPlanIdIn.addAll(JsonHelperUtil.parseArray(payPlanIdInStr, Long.class));
            purchaseIdIn.addAll(JsonHelperUtil.parseArray(data.getString(enumPurchaseId.getAttr()), Long.class));
            supplierIdIn.add(data.getLongValue(enumSupplierId.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //付款计划id-付款计划编号map
        PayPlanEnum payNoEnum = PayPlanEnum.PAY_PLAN_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", payNoEnum.getAttr());
        Map<Long, String> payIdNoMap = formHelp.getFormIdAttrMapByIds4All(payNoEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_PAY_PLAN, payPlanIdIn, fieldList);
        //采购合同id-名称map
        PurchaseEnum purchaseNameEnum = PurchaseEnum.PURCHASE_NAME;
        PurchaseEnum purchaseSerialNumberEnum = PurchaseEnum.SHEET_NO;
        fieldList = Arrays.asList("id", "dataId", PurchaseEnum.getAttrConnectData(purchaseNameEnum), purchaseSerialNumberEnum.getAttr());
        Set<String> attrs = new HashSet<>();
        attrs.add(purchaseNameEnum.getAttr());
        attrs.add(purchaseSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> purchaseIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseIdIn, fieldList);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //查询出回款单的表单id
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的支付方式
        Map<String, String> payTypeMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.PAY_SHEET_PAY_TYPE, corpid, formId);
        int refType4Supplier = XbbRefTypeEnum.SUPPLIER.getCode();
        int refType4PaySheet = XbbRefTypeEnum.PAY_SHEET.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONArray payPlanIdArr = data.getJSONArray(enumPayPlan.getAttr());
            JSONArray purchaseIdArr = data.getJSONArray(enumPurchaseId.getAttr());
            Long supplierId = data.getLong(enumSupplierId.getAttr());
            Long paySheetId = entityExt.getDataId();
            //归属人
            JSONArray uidArr = data.getJSONArray(enumBelongId.getAttr());
            String belongNameStr = commonHelp.getRelationForStr(userNameMap, uidArr);
            String payNo = commonHelp.getRelationNo(payIdNoMap, payPlanIdArr);
            String sheetNo = entityExt.getSerialNo();
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(purchaseIdAttrsMap, purchaseIdArr);
            String relatedPurchaseInfo = getNameNumberInfo(relatedMapList, PurchaseEnum.PURCHASE_NAME.getAttr(), PurchaseEnum.SHEET_NO.getAttr());
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            String payType = payTypeMap.getOrDefault(data.getString(enumPayType.getAttr()), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumBelongId.getAttr(), new TableDataInfoPojo(belongNameStr));
            jsonObject.put(enumPayPlan.getAttr(), new TableDataInfoPojo(payNo));
            jsonObject.put(enumSheetNo.getAttr(), new TableDataInfoPojo(sheetNo, 1, refType4PaySheet, paySheetId));
            jsonObject.put(enumPurchaseId.getAttr(), new TableDataInfoPojo(relatedPurchaseInfo));
            jsonObject.put(enumSupplierId.getAttr(), new TableDataInfoPojo(supplierName, 1, refType4Supplier, supplierId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumWriteOffAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumWriteOffAmount.getAttr()))));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            jsonObject.put(enumPayType.getAttr(), new TableDataInfoPojo(payType));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的未付款业务（付款计划）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 17:47
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPayPlanUn(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PayPlanEnum enumBelongId = PayPlanEnum.BELONGER;
        PayPlanEnum enumNo = PayPlanEnum.PAY_PLAN_NO;
        PayPlanEnum enumPurchaseId = PayPlanEnum.LINK_PURCHASE;
        PayPlanEnum enumSupplierId = PayPlanEnum.LINK_SUPPLIER;
        PayPlanEnum enumAmount = PayPlanEnum.AMOUNT;
        PayPlanEnum enumUnAmount = PayPlanEnum.UN_AMOUNT;
        PayPlanEnum enumStatus = PayPlanEnum.STATUS;
        PayPlanEnum enumTime = PayPlanEnum.ESTIMATE_TIME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumBelongId.getAttr(), I18nMessageUtil.getMessage(BusinessConstant.MAIN_USER), enumBelongId.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumPurchaseId.getAttr(), enumPurchaseId.getAttrName(), enumPurchaseId.getFieldType()));
        title.add(new TitlePojo(enumSupplierId.getAttr(), enumSupplierId.getAttrName(), enumSupplierId.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumUnAmount.getAttr(), enumUnAmount.getAttrName(), enumUnAmount.getFieldType()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        //付款计划id、采购合同ids、供应商id
        Set<Long> payIdIn = new HashSet<>();
        Set<Long> purchaseIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            payIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            purchaseIdIn.add(data.getLongValue(enumPurchaseId.getAttr()));
            supplierIdIn.add(data.getLongValue(enumSupplierId.getAttr()));
        }
        List<PaasFormDataEntity> payPlanUserEntities = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAY_PLAN_TEAM, corpid, payIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<PayPlanUserEntity> teamUserList = (List<PayPlanUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAY_PLAN_TEAM, payPlanUserEntities);
        //payId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //采购合同id-名称map
        PurchaseEnum purchaseNameEnum = PurchaseEnum.PURCHASE_NAME;
        PurchaseEnum purchaseSerialNumberEnum = PurchaseEnum.SHEET_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", purchaseSerialNumberEnum.getAttr(), PurchaseEnum.getAttrConnectData(purchaseNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(purchaseNameEnum.getAttr());
        attrs.add(purchaseSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> purchaseIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseIdIn, fieldList);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        int refType4PayPlan = XbbRefTypeEnum.PAY_PLAN.getCode();
        int refType4Purchase = XbbRefTypeEnum.PURCHASE.getCode();
        int refType4Supplier = XbbRefTypeEnum.SUPPLIER.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long payId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long purchaseId = data.getLong(enumPurchaseId.getAttr());
            JSONArray pidArr = new JSONArray(Collections.singletonList(purchaseId));
            Long supplierId = data.getLong(enumSupplierId.getAttr());
            String owner = ownerNameMap.getOrDefault(payId, "");
            String no = entityExt.getSerialNo();
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(purchaseIdAttrsMap, pidArr);
            String relatedPurchaseInfo = getNameNumberInfo(relatedMapList, PurchaseEnum.PURCHASE_NAME.getAttr(), PurchaseEnum.SHEET_NO.getAttr());
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            String status = PayPlanStatusEnum.getByCode(data.getString(enumStatus.getAttr())).getAlias();
            String timeStr = "";
            Long time = data.getLong(enumTime.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumBelongId.getAttr(), new TableDataInfoPojo(owner));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4PayPlan, payId));
            jsonObject.put(enumPurchaseId.getAttr(), new TableDataInfoPojo(relatedPurchaseInfo, 1, refType4Purchase, purchaseId));
            jsonObject.put(enumSupplierId.getAttr(), new TableDataInfoPojo(supplierName, 1, refType4Supplier, supplierId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumUnAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumUnAmount.getAttr()))));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(timeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的付款计划（已付款、未付款最终都展示付款计划）
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 21:24
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPayPlan4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PAY_PLAN.getCode());
        //付款计划id、采购合同ids、供应商id
        Set<Long> payIdIn = new HashSet<>();
        Set<Long> purchaseIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            payIdIn.add(entityExt.getId());
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            purchaseIdIn.add(data.getLongValue(PayPlanEnum.LINK_PURCHASE.getAttr()));
            supplierIdIn.add(data.getLongValue(PayPlanEnum.LINK_SUPPLIER.getAttr()));
        }
        List<PaasFormDataEntity> payPlanUserEntities = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PAY_PLAN_TEAM, corpid, payIdIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<PayPlanUserEntity> teamUserList = (List<PayPlanUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PAY_PLAN_TEAM, payPlanUserEntities);
        //payId--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //采购合同id-名称map
        PurchaseEnum purchaseNameEnum = PurchaseEnum.PURCHASE_NAME;
        PurchaseEnum purchaseSerialNumberEnum = PurchaseEnum.SHEET_NO;
        List<String> fieldList = Arrays.asList("id", "dataId", purchaseSerialNumberEnum.getAttr(), PurchaseEnum.getAttrConnectData(purchaseNameEnum));
        Set<String> attrs = new HashSet<>();
        attrs.add(purchaseNameEnum.getAttr());
        attrs.add(purchaseSerialNumberEnum.getAttr());
        Map<Long, Map<String, String>> purchaseIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseIdIn, fieldList);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long payId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long purchaseId = data.getLong(PayPlanEnum.LINK_PURCHASE.getAttr());
            JSONArray pidArr = new JSONArray(Collections.singletonList(purchaseId));
            Long supplierId = data.getLong(PayPlanEnum.LINK_SUPPLIER.getAttr());
            String owner = ownerNameMap.getOrDefault(payId, "");
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(purchaseIdAttrsMap, pidArr);
            String relatedPurchaseInfo = getNameNumberInfo(relatedMapList, PurchaseEnum.PURCHASE_NAME.getAttr(), PurchaseEnum.SHEET_NO.getAttr());
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            String status = PayPlanStatusEnum.getByCode(data.getString(PayPlanEnum.STATUS.getAttr())).getAlias();
            String estimateTimeStr = "";
            Long estimateTime = data.getLongValue(PayPlanEnum.ESTIMATE_TIME.getAttr());
            if (estimateTime > 0) {
                estimateTimeStr = DateTimeUtil.getStringEpochSecond(estimateTime, DateTimeUtil.SDFDate);
            }
            String amount = StringUtil.formatDouble(data.getDoubleValue(PayPlanEnum.AMOUNT.getAttr()));
            JSONObject others = new JSONObject();

            /*explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, PayPlanEnum.LINK_PURCHASE.getAttrName(), purchaseName));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, PayPlanEnum.LINK_SUPPLIER.getAttrName(), supplierName));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, "负责人", owner));
*/
            summaryList.add(commonHelp.setSummary(PayPlanEnum.LINK_PURCHASE.getAttrName(), relatedPurchaseInfo));
            summaryList.add(commonHelp.setSummary(PayPlanEnum.LINK_SUPPLIER.getAttrName(), supplierName));
            summaryList.add(commonHelp.setSummary(PayPlanEnum.OWNER_ID.getAttrName(), owner));
            if (!Objects.equals(status, PayPlanStatusEnum.RECEIVABLES.getAlias())) {
                /*explains.add("未付金额：" + StringUtil.formatDouble(data.getDoubleValue(PayPlanEnum.UN_AMOUNT.getAttr())));
                explains.add("已付金额：" + StringUtil.formatDouble(data.getDoubleValue(PayPlanEnum.REAL_AMOUNT.getAttr())));
                explains.add("预计付款日期：" + estimateTimeStr);*/
                summaryList.add(commonHelp.setSummary(PayPlanEnum.UN_AMOUNT.getAttrName(), StringUtil.formatDouble(data.getDoubleValue(PayPlanEnum.UN_AMOUNT.getAttr()))));
                summaryList.add(commonHelp.setSummary(PayPlanEnum.REAL_AMOUNT.getAttrName(), StringUtil.formatDouble(data.getDoubleValue(PayPlanEnum.REAL_AMOUNT.getAttr()))));
                summaryList.add(commonHelp.setSummary(PayPlanEnum.ESTIMATE_TIME.getAttrName(), estimateTimeStr));
            }
            others.put("status", status);
            others.put("amount", amount);

            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            appListPojos.add(new AppListPojo(payId, titleList, summaryList, null, new ArrayList<>(), others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }


    /**
     * 格式化穿透后的付款单业务-app
     *
     * @param corpid 公司id
     * @param list 列表数据
     * @param resultThroughVo 穿透显示数据
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws
     * @author 徐俊杰
     * @date 2020/3/16 15:44
     * @since v1.0
     */
    private ResultThroughVO formatPaySheet4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PaySheetEnum enumPurchaseId = PaySheetEnum.LINK_PURCHASE;
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode());
        Set<String> userIdIn = new HashSet<>();
        Set<Long> purchaseIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            JSONArray signPerson = getJsonArrOrDefaultFromFormData(data, PaySheetEnum.BELONG_ID.getAttr(), new JSONArray());
            userIdIn.addAll(JSONArray.parseArray(signPerson.toJSONString(),String.class));
            purchaseIdIn.addAll(JsonHelperUtil.parseArray(data.getString(enumPurchaseId.getAttr()), Long.class));
        }
        //获取采购合同相关信息
        List<String> fieldList = Arrays.asList("id", "dataId", PurchaseEnum.SHEET_NO.getAttr(), PurchaseEnum.getAttrConnectData(PurchaseEnum.PURCHASE_NAME));
        Set<String> attrs = new HashSet<>();
        attrs.add(PurchaseEnum.PURCHASE_NAME.getAttr());
        attrs.add(PurchaseEnum.SHEET_NO.getAttr());
        Map<Long, Map<String, String>> purchaseIdAttrsMap = formHelp.getIdAttrMapsByIds(attrs, corpid, IndexTypeEnum.IDX_SAAS_PURCHASE, purchaseIdIn, fieldList);
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            Long dataId = entityExt.getDataId();
            List<FormTitlePoJo> titleList = new ArrayList<>();
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            JSONObject data = entityExt.getData();
            //供应商
            String supplierName = data.getString(PaySheetEnum.SUPPLIER_LINK_TEXT.getAttr());
            summaryList.add(commonHelp.setSummary(PaySheetEnum.LINK_SUPPLIER.getAttrName(), supplierName));
            //采购合同
            JSONArray puridArr = data.getJSONArray(enumPurchaseId.getAttr());
            List<Map<String, String>> relatedMapList = commonHelp.getRelatedMapList(purchaseIdAttrsMap, puridArr);
            String relatedPurchaseInfo = getNameNumberInfo(relatedMapList, PurchaseEnum.PURCHASE_NAME.getAttr(), PurchaseEnum.SHEET_NO.getAttr());
            summaryList.add(commonHelp.setSummary(PaySheetEnum.LINK_PURCHASE.getAttrName(), relatedPurchaseInfo));
            //归属人
            String belongNameStr = "";
            JSONArray uidArr = data.getJSONArray(PaySheetEnum.BELONG_ID.getAttr());
            belongNameStr = commonHelp.getRelationForStr(userNameMap, uidArr);
            summaryList.add(commonHelp.setSummary(PaySheetEnum.BELONG_ID.getAttrName(), belongNameStr));
            //付款日期
            String timeStr = "";
            Long time = data.getLong(PaySheetEnum.REAL_PAY_TIME.getAttr());
            if (time != null && time > 0) {
                timeStr = DateTimeUtil.getStringEpochSecond(time, DateTimeUtil.SDFDate);
            }
            summaryList.add(commonHelp.setSummary(PaySheetEnum.REAL_PAY_TIME.getAttrName(), timeStr));
            JSONObject others = disposePaySheetOthers(data);
            //汇总
            appListPojos.add(new AppListPojo(entityExt.getId(), titleList, summaryList, new JSONObject(), new ArrayList<>(), others, entityExt.getAppId(), entityExt.getMenuId(), entityExt.getFormId()));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的采购合同业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 18:06
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPurchase(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        PurchaseEnum enumName = PurchaseEnum.PURCHASE_NAME;
        PurchaseEnum enumNo = PurchaseEnum.SHEET_NO;
        PurchaseEnum enumAmount = PurchaseEnum.TOTAL_MONEY;
        PurchaseEnum enumStatus = PurchaseEnum.STATUS;
        PurchaseEnum enumSupplierId = PurchaseEnum.SUPPLIER_ID;
        PurchaseEnum enumSignPerson = PurchaseEnum.SIGNER_ID;
        PurchaseEnum enumTime = PurchaseEnum.SIGN_TIME;
        PurchaseEnum enumDeadline = PurchaseEnum.ESTIMATE_ARRIVE_TIME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumSupplierId.getAttr(), enumSupplierId.getAttrName(), enumSupplierId.getFieldType()));
        title.add(new TitlePojo(enumSignPerson.getAttr(), enumSignPerson.getAttrName(), enumSignPerson.getFieldType()));
        title.add(new TitlePojo(enumTime.getAttr(), enumTime.getAttrName(), enumTime.getFieldType()));
        title.add(new TitlePojo(enumDeadline.getAttr(), enumDeadline.getAttrName(), enumDeadline.getFieldType()));
        //签订人ids、采购合同ids、供应商id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(enumSignPerson.getAttr()));
            supplierIdIn.add(data.getLongValue(enumSupplierId.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //查询出采购合同的表单id
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PURCHASE.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的采购合同状态
        Map<String, String> purchaseStatusMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.PURCHASE_STATUS, corpid, formId);
        int refType4Purchase = XbbRefTypeEnum.PURCHASE.getCode();
        int refType4Supplier = XbbRefTypeEnum.SUPPLIER.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long purchaseId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long supplierId = data.getLong(enumSupplierId.getAttr());
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), ""));
            name = Objects.equals(name, "null")?"":name;
            String no = entityExt.getSerialNo();
            String status = purchaseStatusMap.getOrDefault(data.getString(enumStatus.getAttr()), "");
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            //签订人
            String belongNameStr = userNameMap.getOrDefault(data.getString(enumSignPerson.getAttr()), "");
            String estimateArriveTimeStr = "";
            Long estimateArriveTime = data.getLong(enumDeadline.getAttr());
            if (estimateArriveTime != null && estimateArriveTime > 0) {
                estimateArriveTimeStr = DateTimeUtil.getStringEpochSecond(estimateArriveTime, DateTimeUtil.SDFDate);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType4Purchase, purchaseId));
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType4Purchase, purchaseId));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumSupplierId.getAttr(), new TableDataInfoPojo(supplierName, 1, refType4Supplier, supplierId));
            jsonObject.put(enumSignPerson.getAttr(), new TableDataInfoPojo(belongNameStr));
            jsonObject.put(enumTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(data.getLong(enumTime.getAttr()), DateTimeUtil.SDFDate)));
            jsonObject.put(enumDeadline.getAttr(), new TableDataInfoPojo(estimateArriveTimeStr));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的采购合同业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 21:47
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatPurchase4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
        //签订人ids、采购合同ids、供应商id
        Set<String> userIdIn = new HashSet<>();
        Set<Long> supplierIdIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userIdIn.add(data.getString(PurchaseEnum.SIGNER_ID.getAttr()));
            supplierIdIn.add(data.getLongValue(PurchaseEnum.SUPPLIER_ID.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //供应商id-名称map
        SupplierEnum supplierNameEnum = SupplierEnum.SUPPLIER_NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", SupplierEnum.getAttrConnectData(supplierNameEnum));
        Map<Long, String> supplierIdNameMap = formHelp.getFormIdAttrMapByIds4All(supplierNameEnum.getAttr(), corpid, IndexTypeEnum.IDX_SAAS_SUPPLIER, supplierIdIn, fieldList);
        //查询出采购合同的表单id
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PURCHASE.getCode(), corpid);
        Long formId = paasFormEntityExt == null ? null : paasFormEntityExt.getId();
        //获取启用的采购合同状态
        Map<String, String> purchaseStatusMap = dataDictionaryModel.getDictionaryMap4Saas(DictionaryEnum.PURCHASE_STATUS, corpid, formId);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long purchaseId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            Long supplierId = data.getLong(PurchaseEnum.SUPPLIER_ID.getAttr());
            String status = purchaseStatusMap.getOrDefault(data.getString(PurchaseEnum.STATUS.getAttr()), "");
            String supplierName = supplierIdNameMap.getOrDefault(supplierId, "");
            Long signTime = data.getLongValue(PurchaseEnum.SIGN_TIME.getAttr());
            String signTimeStr = DateTimeUtil.getStringEpochSecond(signTime, DateTimeUtil.SDFDate);
            //签订人
            String belongNameStr = userNameMap.getOrDefault(data.getString(PurchaseEnum.SIGNER_ID.getAttr()), "");
            JSONObject others = new JSONObject();

            /*explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, PurchaseEnum.SUPPLIER_ID.getAttrName(), supplierName));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, PurchaseEnum.SIGNER_ID.getAttrName(), belongNameStr));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, PurchaseEnum.SIGN_TIME.getAttrName(), signTimeStr));*/
            summaryList.add(commonHelp.setSummary(PurchaseEnum.SUPPLIER_ID.getAttrName(), supplierName));
            summaryList.add(commonHelp.setSummary(PurchaseEnum.SIGNER_ID.getAttrName(), belongNameStr));
            summaryList.add(commonHelp.setSummary(PurchaseEnum.SIGN_TIME.getAttrName(), signTimeStr));

            String amount = StringUtil.formatDouble(data.getDoubleValue(PurchaseEnum.TOTAL_MONEY.getAttr()));
            String unit = I18nMessageUtil.getMessage(CommonConstant.YUAN);
            others.put(PurchaseEnum.TOTAL_MONEY.getSaasAttr(), amount + unit);
            if (!StringUtil.isEmpty(status)) {
                //tags.add(status);
                lablesList.add(commonHelp.setLable(PurchaseEnum.TOTAL_MONEY.getAttrName(), amount + unit));
            }
            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            appListPojos.add(new AppListPojo(purchaseId, titleList, summaryList, null, lablesList, others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的生产单业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/4 19:36
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductionOrder(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        ProductionOrderEnum enumNo = ProductionOrderEnum.SHEET_NO;
        ProductionOrderEnum enumOwner = ProductionOrderEnum.OWNER_ID;
        ProductionOrderEnum enumPlanTime = ProductionOrderEnum.PLAN_TIME;
        ProductionOrderEnum enumCompleteTime = ProductionOrderEnum.COMPLETE_TIME;
        //耗时情况，库内并无该字段，只是为了渲染，因此使用ProductionOrderEnum内的一个memo字段标识，实际显示数据并不会展示这个memo字段的值
        ProductionOrderEnum enumTimeConsuming = ProductionOrderEnum.MEMO;
        ProductionOrderEnum enumStatus = ProductionOrderEnum.STATUS;
        ProductionOrderEnum enumCreator = ProductionOrderEnum.CREATOR_ID;
        ProductionOrderEnum enumAddTime = ProductionOrderEnum.ADD_TIME;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumNo.getAttr(), enumNo.getAttrName(), enumNo.getFieldType()));
        title.add(new TitlePojo(enumOwner.getAttr(), enumOwner.getAttrName()));
        title.add(new TitlePojo(enumPlanTime.getAttr(), enumPlanTime.getAttrName(), enumPlanTime.getFieldType()));
        title.add(new TitlePojo(enumCompleteTime.getAttr(), enumCompleteTime.getAttrName(), enumCompleteTime.getFieldType()));
        title.add(new TitlePojo(enumTimeConsuming.getAttr(), enumTimeConsuming.getAttrName(), enumTimeConsuming.getFieldType()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumCreator.getAttr(), enumCreator.getAttrName(), enumCreator.getFieldType()));
        title.add(new TitlePojo(enumAddTime.getAttr(), enumAddTime.getAttrName(), enumAddTime.getFieldType()));
        //创建人ids、生产单ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> idIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            userIdIn.add(entityExt.getCreatorId());
            idIn.add(entityExt.getId());
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<PaasFormDataEntity> productUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER_TEAM, corpid, idIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<ProductionOrderUserEntity> teamUserList = (List<ProductionOrderUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER_TEAM, productUserList);
        //生产单id--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        int refType = XbbRefTypeEnum.PRODUCTION_ORDER.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        ProductionOrderEnum enumCloseTime = ProductionOrderEnum.CLOSE_TIME;
        for (PaasFormDataEntityExt entityExt : list) {
            Long productionOrderId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String no = entityExt.getSerialNo();
            String owner = ownerNameMap.getOrDefault(productionOrderId, "");
            String planTimeStr = "";
            Long planTime = data.getLong(enumPlanTime.getAttr());
            if (planTime != null && planTime > 0) {
                planTimeStr = DateTimeUtil.getStringEpochSecond(planTime, DateTimeUtil.SDFDate);
            }
            String completeTimeStr = "";
            Long completeTime = data.getLong(enumCompleteTime.getAttr());
            if (completeTime != null && completeTime > 0) {
                completeTimeStr = DateTimeUtil.getStringEpochSecond(completeTime, DateTimeUtil.SDFDate);
            }
            String timeConsuming = "";
            ProductionOrderStatusEnum statusEnum = ProductionOrderStatusEnum.getByCode(data.getInteger(enumStatus.getAttr()));
            Long closeTime = data.getLong(enumCloseTime.getAttr());
            if (commonHelp.ifNotOvertime(planTime, completeTime, closeTime, statusEnum)) {
                timeConsuming = I18nMessageUtil.getMessage(I18nStringConstant.NOT_TIMED_OUT);
            } else {
                timeConsuming = I18nMessageUtil.getMessage(I18nStringConstant.TIMED_OUT);
            }
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(no, 1, refType, productionOrderId));
            jsonObject.put(enumOwner.getAttr(), new TableDataInfoPojo(owner));
            jsonObject.put(enumPlanTime.getAttr(), new TableDataInfoPojo(planTimeStr));
            jsonObject.put(enumCompleteTime.getAttr(), new TableDataInfoPojo(completeTimeStr));
            jsonObject.put(enumTimeConsuming.getAttr(), new TableDataInfoPojo(timeConsuming));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(statusEnum.getAlias()));
            jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
            jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entityExt.getAddTime())));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的生产单业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/16 22:08
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatProductionOrder4App(String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
        //创建人ids、生产单ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> idIn = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : list) {
            userIdIn.add(entityExt.getCreatorId());
            idIn.add(entityExt.getId());
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        List<PaasFormDataEntity> productUserList = formHelp.getUserTeamListByIds(IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER_TEAM, corpid, idIn, BasicConstant.MAIN_USER, PaasFormDataEntity.class);
        List<ProductionOrderUserEntity> teamUserList = (List<ProductionOrderUserEntity>) transferSubFormHelper.transferFormDataToUserTeamList(IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER_TEAM, productUserList);
        //生产单id--负责人名称
        Map<Long, String> ownerNameMap = commonHelp.getUserTeamNameMap(teamUserList);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long productionOrderId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String no = entityExt.getSerialNo();
            String owner = ownerNameMap.getOrDefault(productionOrderId, "");
            String creator = userNameMap.getOrDefault(entityExt.getCreatorId(), "");
            String planTimeStr = "";
            Long planTime = data.getLongValue(ProductionOrderEnum.PLAN_TIME.getAttr());
            if (planTime > 0) {
                planTimeStr = DateTimeUtil.getStringEpochSecond(planTime, DateTimeUtil.SDFDate);
            }
            String completeTimeStr = "";
            Long completeTime = data.getLongValue(ProductionOrderEnum.COMPLETE_TIME.getAttr());
            if (completeTime > 0) {
                completeTimeStr = DateTimeUtil.getStringEpochSecond(completeTime, DateTimeUtil.SDFDate);
            }
            ProductionOrderStatusEnum statusEnum = ProductionOrderStatusEnum.getByCode(data.getInteger(ProductionOrderEnum.STATUS.getAttr()));

            JSONObject others = new JSONObject();
            /*explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.SHEET_NO.getAttrName(), no));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.OWNER_ID.getAttrName(), owner));
            explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.CREATOR_ID.getAttrName(), creator));*/
            summaryList.add(commonHelp.setSummary(ProductionOrderEnum.SHEET_NO.getAttrName(), no));
            summaryList.add(commonHelp.setSummary(ProductionOrderEnum.OWNER_ID.getAttrName(), owner));
            summaryList.add(commonHelp.setSummary(ProductionOrderEnum.CREATOR_ID.getAttrName(), creator));

            Long closeTime = data.getLong(ProductionOrderEnum.CLOSE_TIME.getAttr());
            if (commonHelp.ifNotOvertime(planTime, completeTime, closeTime, statusEnum)) {
                //explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.PLAN_TIME.getAttrName(), planTimeStr));
                summaryList.add(commonHelp.setSummary(ProductionOrderEnum.PLAN_TIME.getAttrName(), planTimeStr));
            } else {
                //explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.PLAN_TIME.getAttrName(), planTimeStr + "（已逾期）"));
                summaryList.add(commonHelp.setSummary(ProductionOrderEnum.PLAN_TIME.getAttrName(), planTimeStr + "（" + I18nMessageUtil.getMessage(I18nStringConstant.OVERDUE) + "）"));
                others.put("color", "red");
            }
            //explains.add(String.format(StringConstant.APP_LIST_VALUE_SHOW, ProductionOrderEnum.COMPLETE_TIME.getAttrName(), completeTimeStr));
            summaryList.add(commonHelp.setSummary(ProductionOrderEnum.COMPLETE_TIME.getAttrName(), completeTimeStr));

            others.put(ProductionOrderEnum.STATUS.getSaasAttr(), statusEnum.getAlias());

            titleList.add(commonHelp.setTitle(entityExt.getSerialNo()));
            appListPojos.add(new AppListPojo(productionOrderId, titleList, summaryList, null, new ArrayList<>(), others));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 格式化穿透后的工单业务
     * @param indicatorRuleEnum 工单指标类型
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/5 16:26
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatWorkOrder(IndicatorRuleEnum indicatorRuleEnum, String corpid, List<WorkOrderEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        //工单编号未在data内
        WorkOrderEnum enumCustomerId = WorkOrderEnum.LINK_CUSTOMER;
        List<TitlePojo> title = getTitle4WorkOrder(indicatorRuleEnum);
        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        Set<Long> customerIdIn = new HashSet<>();
        for (WorkOrderEntity entity : list) {
            userIdIn.add(entity.getCreatorId());
            JSONObject data = JsonHelperUtil.getJSONObject(entity.getData());
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        int refType4WorkOrder = XbbRefTypeEnum.WORK_ORDER.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (WorkOrderEntity entity : list) {
            JSONObject jsonObject = getWorkOrderData(indicatorRuleEnum, entity, refType4WorkOrder, refType4Customer, customerIdNameMap, userNameMap);
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的工单业务
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException
     * @author zcp
     * @date 2019/5/17 14:09
     * @since v1.0
     * @version v1.0
     */
    private ResultThroughVO formatWorkOrder4App(String corpid, List<WorkOrderEntity> list, ResultThroughVO resultThroughVo) throws XbbException {
        resultThroughVo.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        //创建人ids、客户ids
        Set<String> userIdIn = new HashSet<>();
        //模板ids
        Set<Long> templateIds = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        for (WorkOrderEntity entity : list) {
            userIdIn.add(entity.getCreatorId());
            templateIds.add(entity.getTemplateId());
            formIds.add(entity.getFormId());
        }
        List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.getByFormIdIn(formIds, corpid);
        Map<Long, FieldAttrEntity> formIdAndFieldAttrMap = new HashMap<>();
        for (WorkOrderExplainEntity workOrderExplainEntity : workOrderExplainEntities) {
            List<FieldAttrEntity> fieldAttrEntities = JSON.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.CONTACT_INFORMATION.getAttr())) {
                    formIdAndFieldAttrMap.put(workOrderExplainEntity.getFormId(), fieldAttrEntity);
                }
            }
        }
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        Map<Long, WorkOrderTemplateEntity> templateMap = workOrderTemplateModel.getTemplateMap(templateIds, corpid);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (WorkOrderEntity entity : list) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long orderId = entity.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entity.getData());
            //工单编号
            String sheetNo = entity.getSerialNo();
            String creator = userNameMap.getOrDefault(entity.getCreatorId(), "");
            //实施时间
            String implementationTimeStr = I18nMessageUtil.getMessage(CommonConstant.NOTHING);
            Long implementationTime = data.getLongValue(WorkOrderEnum.IMPLEMENTATION_TIME.getAttr());
            if (implementationTime > 0) {
                implementationTimeStr = DateTimeUtil.getStringEpochSecond(implementationTime);
            }
            String price = StringUtil.formatDouble(data.getDoubleValue(WorkOrderEnum.SERVICE_PRICE.getAttr()));
            //实施地址
            String address = commonHelp.formatAddress(data, WorkOrderEnum.ADDRESS.getAttr());

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            //解释
            /*explains.add("实施时间:" + implementationTimeStr);
            explains.add("创建人:" + creator);
            explains.add("服务价格:" + price);
            explains.add("实施地址:" + address);*/
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.IMPLEMENTATION_TIME.getAttrName(), implementationTimeStr));
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.CREATOR_ID.getAttrName(), creator));
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.SERVICE_PRICE.getAttrName(), price));
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.ADDRESS.getAttrName(), address));
            //角标
            Integer emergency = data.getIntValue(WorkOrderEnum.EMERGENCY_LEVEL.getAttr());
            superScript.put("emergency", emergency);
            //其他
            Integer status = entity.getStatus();
            String statusStr = WorkOrderStatusEnum.getByCode(status).getName();
            TimeConsumingOutPojo timeConsumingOutPojo = commonHelp.workOrderConsueTime(entity);
            //工单模板
            WorkOrderTemplateEntity workOrderTemplateEntity = templateMap.get(entity.getTemplateId());
            boolean isLimit = false;
            if (Objects.nonNull(workOrderTemplateEntity) && Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0)) {
                isLimit = true;
            }
            if (isLimit) {
                others.put("consumeTime", "");
                others.put("isOut", 0);
            } else {
                others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                others.put("isOut", timeConsumingOutPojo.getIsOut());
            }

            List<MobileDetailDialPhonePojo> phoneList = new ArrayList<>();
            JSONArray phoneArray = data.getJSONArray(WorkOrderEnum.CONTACT_INFORMATION.getAttr());
            FieldAttrEntity subFormAttr = commonHelp.getSubFormAttr(formIdAndFieldAttrMap.get(entity.getFormId()));
            phoneList.addAll(commonHelp.handleDialPhone(phoneArray, null, RedundantTemplateTypeEnum.WORKORDER.getCode(), orderId,null,subFormAttr, null));
            others.put("phone", phoneList);
            others.put("statusStr", statusStr);
            others.put("status", status);
            others.put("rateStar", data.getIntValue(WorkOrderEnum.RATE_STAR.getAttr()));
            Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();

            titleList.add(commonHelp.setTitle(sheetNo));
            appListPojos.add(new AppListPojo(orderId, titleList, summaryList, superScript, new ArrayList<>(), others, businessType));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 封装工单穿透后的表格标题
     * @param indicatorRuleEnum 工单指标类型
     * @return java.util.List<com.xbongbong.pro.statistic.result.pojo.TitlePojo>
     * @author zcp
     * @date 2019/5/5 10:45
     * @since v1.0
     * @version v1.0
     */
    private List<TitlePojo> getTitle4WorkOrder(IndicatorRuleEnum indicatorRuleEnum) {
        List<TitlePojo> title = new ArrayList<>();
        //工单编号、客户名称、联系方式、创建人、星级
        title.add(new TitlePojo(WorkOrderEnum.SHEET_NO.getAttr(), WorkOrderEnum.SHEET_NO.getAttrName(), WorkOrderEnum.SHEET_NO.getFieldType()));
        title.add(new TitlePojo(WorkOrderEnum.LINK_CUSTOMER.getAttr(), WorkOrderEnum.LINK_CUSTOMER.getAttrName(), WorkOrderEnum.LINK_CUSTOMER.getFieldType()));
        title.add(new TitlePojo(WorkOrderEnum.CONTACT_INFORMATION.getAttr(), WorkOrderEnum.CONTACT_INFORMATION.getAttrName(), WorkOrderEnum.CONTACT_INFORMATION.getFieldType()));
        title.add(new TitlePojo(WorkOrderEnum.CREATOR_ID.getAttr(), WorkOrderEnum.CREATOR_ID.getAttrName(),WorkOrderEnum.CREATOR_ID.getFieldType()));
        title.add(new TitlePojo(WorkOrderEnum.RATE_STAR.getAttr(), WorkOrderEnum.RATE_STAR.getAttrName(), FieldTypeEnum.STAR.getType()));
        switch (indicatorRuleEnum) {
            case WORK_ORDER_TOTAL:
            case WORK_ORDER_ADD:
            case WORK_ORDER_PRICE:
            case WORK_ORDER_DEGREE:
                //实施时间、服务价格、创建时间
                title.add(new TitlePojo(WorkOrderEnum.IMPLEMENTATION_TIME.getAttr(), WorkOrderEnum.IMPLEMENTATION_TIME.getAttrName(), WorkOrderEnum.IMPLEMENTATION_TIME.getFieldType()));
                title.add(new TitlePojo(WorkOrderEnum.SERVICE_PRICE.getAttr(), WorkOrderEnum.SERVICE_PRICE.getAttrName(), WorkOrderEnum.SERVICE_PRICE.getFieldType()));
                title.add(new TitlePojo(WorkOrderEnum.ADD_TIME.getAttr(), WorkOrderEnum.ADD_TIME.getAttrName(), WorkOrderEnum.ADD_TIME.getFieldType()));
                break;
            case WORK_ORDER_CLOSE:
                //关闭时间
                title.add(new TitlePojo(WorkOrderEnum.CLOSE_TIME.getAttr(), WorkOrderEnum.CLOSE_TIME.getAttrName(), WorkOrderEnum.CLOSE_TIME.getFieldType()));
                break;
            case WORK_ORDER_FINISH:
            case WORK_ORDER_FINISH_DELAY:
            case WORK_ORDER_FINISH_INTIME:
                //完成时间、预计耗时、实际耗时
                title.add(new TitlePojo(WorkOrderEnum.COMPLETE_TIME.getAttr(), WorkOrderEnum.COMPLETE_TIME.getAttrName(), WorkOrderEnum.COMPLETE_TIME.getFieldType()));
                title.add(new TitlePojo(WorkOrderForStatisticsEnum.EXPECTED_TIME.getAttr(), WorkOrderForStatisticsEnum.EXPECTED_TIME.getAttrName()));
                title.add(new TitlePojo(WorkOrderForStatisticsEnum.ACTUAL_TIME.getAttr(), WorkOrderForStatisticsEnum.ACTUAL_TIME.getAttrName()));
                break;
            default:
                title = new ArrayList<>();
                break;
        }
        return title;
    }
    /**
     * 封装工单表格数据
     * @param indicatorRuleEnum 工单指标类型
     * @param entity 工单实体
     * @param refType4WorkOrder 工单refType
     * @param refType4Customer 客户refType
     * @param customerIdNameMap 客户id-名称map
     * @param userNameMap 员工id--员工名称
     * @return com.alibaba.fastjson.JSONObject
     * @author zcp
     * @date 2019/5/5 16:21
     * @since v1.0
     * @version v1.0
     */
    private JSONObject getWorkOrderData(IndicatorRuleEnum indicatorRuleEnum, WorkOrderEntity entity, int refType4WorkOrder, int refType4Customer, Map<Long, String> customerIdNameMap, Map<String, String> userNameMap) {
        //工单编号、客户名称、联系方式、创建人、星级
        WorkOrderEnum enumNo = WorkOrderEnum.SHEET_NO;
        WorkOrderEnum enumCustomerId = WorkOrderEnum.LINK_CUSTOMER;
        WorkOrderEnum enumPhone = WorkOrderEnum.CONTACT_INFORMATION;
        WorkOrderEnum enumCreator = WorkOrderEnum.CREATOR_ID;
        WorkOrderEnum enumStar = WorkOrderEnum.RATE_STAR;

        Long orderId = entity.getId();
        JSONObject data = JsonHelperUtil.getJSONObject(entity.getData());
        Long customerId = data.getLong(enumCustomerId.getAttr());
        String customerName = customerIdNameMap.getOrDefault(customerId, "");
        JSONArray phoneJsonArray = data.getJSONArray(enumPhone.getAttr());
        String phone = commonHelp.formatPhone(phoneJsonArray);
        String creator = userNameMap.getOrDefault(entity.getCreatorId(), "");
        Integer star = data.getIntValue(enumStar.getAttr());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(enumNo.getAttr(), new TableDataInfoPojo(entity.getSerialNo(), 1, refType4WorkOrder, orderId));
        jsonObject.put(enumCustomerId.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
        jsonObject.put(enumPhone.getAttr(), new TableDataInfoPojo(phone));
        jsonObject.put(enumCreator.getAttr(), new TableDataInfoPojo(creator));
        jsonObject.put(enumStar.getAttr(), new TableDataInfoPojo(star.toString()));
        String timeStr = "";
        Long time;
        switch (indicatorRuleEnum){
            case WORK_ORDER_TOTAL:
            case WORK_ORDER_ADD:
            case WORK_ORDER_PRICE:
            case WORK_ORDER_DEGREE:
                //实施时间、服务价格、创建时间
                WorkOrderEnum enumImplementationTime = WorkOrderEnum.IMPLEMENTATION_TIME;
                WorkOrderEnum enumPrice = WorkOrderEnum.SERVICE_PRICE;
                WorkOrderEnum enumAddTime = WorkOrderEnum.ADD_TIME;
                time = data.getLong(enumImplementationTime.getAttr());
                if (time != null && time > 0) {
                    timeStr = DateTimeUtil.getStringEpochSecond(time);
                }
                jsonObject.put(enumImplementationTime.getAttr(), new TableDataInfoPojo(timeStr));
                jsonObject.put(enumPrice.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumPrice.getAttr()))));
                jsonObject.put(enumAddTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(entity.getAddTime())));
                break;
            case WORK_ORDER_CLOSE:
                //关闭时间
                WorkOrderEnum enumCloseTime = WorkOrderEnum.CLOSE_TIME;
                time = data.getLong(enumCloseTime.getAttr());
                if (time != null && time > 0) {
                    timeStr = DateTimeUtil.getStringEpochSecond(time);
                }
                jsonObject.put(enumCloseTime.getAttr(), new TableDataInfoPojo(timeStr));
                break;
            case WORK_ORDER_FINISH:
            case WORK_ORDER_FINISH_DELAY:
            case WORK_ORDER_FINISH_INTIME:
                //完成时间、预计耗时、实际耗时
                WorkOrderEnum enumEndTime = WorkOrderEnum.COMPLETE_TIME;
                WorkOrderForStatisticsEnum enumExpectedTime = WorkOrderForStatisticsEnum.EXPECTED_TIME;
                WorkOrderForStatisticsEnum enumActualTime = WorkOrderForStatisticsEnum.ACTUAL_TIME;
                Long endTime = entity.getEndTime();
                if (endTime != null && endTime > 0) {
                    timeStr = DateTimeUtil.getStringEpochSecond(endTime);
                }
                Integer expectedTime = entity.getExpectedTime();
                Integer actualTime = entity.getActualTime();
                String expectedTimeStr = commonHelp.secondsToPersonalTime(expectedTime, I18nMessageUtil.getMessage(I18nStringConstant.EXPECTED_TIME));
                String actualTimeStr = commonHelp.secondsToPersonalTime(actualTime, I18nMessageUtil.getMessage(I18nStringConstant.TIME_CONSUMING));

                jsonObject.put(enumEndTime.getAttr(), new TableDataInfoPojo(timeStr));
                jsonObject.put(enumExpectedTime.getAttr(), new TableDataInfoPojo(expectedTimeStr));
                jsonObject.put(enumActualTime.getAttr(), new TableDataInfoPojo(actualTimeStr));
                break;
            default:
                break;
        }
        return jsonObject;
    }

    /**
     * 格式化穿透后的报价单
     *
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/8/26 16:33
     * @since v1.0
     */
    private ResultThroughVO formatQuotation(IndicatorRuleEnum indicatorRuleEnum, String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        //报价单客户数穿透页面展示客户详细信息
        if (IndicatorRuleEnum.QUOTATION_CUSTOMER_COUNT == indicatorRuleEnum) {
            return formatCustomer(false,false, false, corpid, list, resultThroughVo);
        }
        QuotationEnum enumNumber = QuotationEnum.QUOTATION_NO;
        QuotationEnum enumName = QuotationEnum.NAME;
        QuotationEnum enumAmount = QuotationEnum.AMOUNT;
        QuotationEnum enumStatus = QuotationEnum.STATUS;
        QuotationEnum enumCustomerName = QuotationEnum.CUSTOMER_NAME;
        QuotationEnum enumQuotationName = QuotationEnum.QUOTATION_NAME;
        QuotationEnum enumQuotationTime = QuotationEnum.QUOTATION_TIME;
        QuotationEnum enumEffectiveTime = QuotationEnum.EFFECTIVE_TIME;
        QuotationEnum enumCustomerId = QuotationEnum.CUSTOMER_ID;
        QuotationEnum enumQuotationPerson = QuotationEnum.QUOTATION_PERSON;
        List<TitlePojo> title = new ArrayList<>();
        title.add(new TitlePojo(enumNumber.getAttr(), enumNumber.getAttrName(), enumNumber.getFieldType()));
        title.add(new TitlePojo(enumName.getAttr(), enumName.getAttrName(), enumName.getFieldType()));
        title.add(new TitlePojo(enumAmount.getAttr(), enumAmount.getAttrName(), enumAmount.getFieldType()));
        title.add(new TitlePojo(enumStatus.getAttr(), enumStatus.getAttrName(), enumStatus.getFieldType()));
        title.add(new TitlePojo(enumCustomerName.getAttr(), enumCustomerName.getAttrName(), enumCustomerName.getFieldType()));
        title.add(new TitlePojo(enumQuotationName.getAttr(), enumQuotationName.getAttrName(), enumQuotationName.getFieldType()));
        title.add(new TitlePojo(enumQuotationTime.getAttr(), enumQuotationTime.getAttrName(), enumQuotationTime.getFieldType()));
        title.add(new TitlePojo(enumEffectiveTime.getAttr(), enumEffectiveTime.getAttrName(), enumEffectiveTime.getFieldType()));
        //报价人ids、客户ids
        Set<Long> customerIdIn = new HashSet<>();
        Set<String> userIdIn = new HashSet<>();
        Map<Long, String> userNameMapStr = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            userNameMapStr.put(entityExt.getDataId(), data.getString(enumQuotationName.getAttr()) + StringConstant.LEAVE_ANOTHER_MARK);
            customerIdIn.add(data.getLongValue(enumCustomerId.getAttr()));
            userIdIn.add(data.getString(enumQuotationPerson.getAttr()));
        }
        //报价状态
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.QUOTATION.getCode(), corpid);
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, String> valueTextMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FieldAttrEntity entity : explainList) {
            String attr = entity.getAttr();
            if (Objects.equals(QuotationEnum.STATUS.getAttr(), attr)) {
                List<ItemPoJo> items = entity.getItems();
                for (ItemPoJo item : items) {
                    String value = (String) item.getValue();
                    String text = item.getText();
                    valueTextMap.put(value, text);
                }
            }
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //关联业务
        int refType4Quotation = XbbRefTypeEnum.QUOTATION.getCode();
        int refType4Customer = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        //最终结果
        JSONArray resultData = new JSONArray();
        for (PaasFormDataEntityExt entityExt : list) {
            Long id = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String number = entityExt.getSerialNo();
            String name = String.valueOf(data.getOrDefault(enumName.getAttr(), ""));
            String value =  (String) data.getOrDefault(enumStatus.getAttr(), "0");
            String status = valueTextMap.getOrDefault(value, "");
            Long customerId = data.getLong(enumCustomerId.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String quotationPersonName = userNameMap.getOrDefault(data.getString(enumQuotationPerson.getAttr()), userNameMapStr.getOrDefault(id, ""));
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(enumNumber.getAttr(), new TableDataInfoPojo(number, 1, refType4Quotation, id));
            jsonObject.put(enumName.getAttr(), new TableDataInfoPojo(name, 1, refType4Quotation, id));
            jsonObject.put(enumAmount.getAttr(), new TableDataInfoPojo(StringUtil.formatDouble(data.getDoubleValue(enumAmount.getAttr()))));
            jsonObject.put(enumStatus.getAttr(), new TableDataInfoPojo(status));
            jsonObject.put(enumCustomerName.getAttr(), new TableDataInfoPojo(customerName, 1, refType4Customer, customerId));
            jsonObject.put(enumQuotationName.getAttr(), new TableDataInfoPojo(quotationPersonName));
            jsonObject.put(enumQuotationTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(data.getLong(enumQuotationTime.getAttr()), DateTimeUtil.SDFDate)));
            jsonObject.put(enumEffectiveTime.getAttr(), new TableDataInfoPojo(DateTimeUtil.getStringEpochSecond(data.getLong(enumEffectiveTime.getAttr()), DateTimeUtil.SDFDate)));
            resultData.add(jsonObject);
        }
        resultThroughVo.setTitle(title);
        resultThroughVo.setData(resultData);
        return resultThroughVo;
    }

    /**
     * app端：格式化穿透后的报价单业务
     *
     * @param indicatorRuleEnum 指标类型枚举
     * @param corpid 公司id
     * @param list 业务list
     * @param resultThroughVo 穿透返回vo
     * @return com.xbongbong.pro.statistic.through.pojo.vo.ResultThroughVO
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/8/26 14:40
     * @since v1.0
     */
    private ResultThroughVO formatQuotation4App(IndicatorRuleEnum indicatorRuleEnum, String corpid, List<PaasFormDataEntityExt> list, ResultThroughVO resultThroughVo) throws XbbException {
        //报价单客户数穿透页面展示客户详细信息
        if (IndicatorRuleEnum.QUOTATION_CUSTOMER_COUNT == indicatorRuleEnum) {
            return formatCustomer4App(false,false,false, corpid, list, resultThroughVo);
        }
        resultThroughVo.setBusinessType(XbbRefTypeEnum.QUOTATION.getCode());
        //签订人ids、客户id
        Set<Long> customerIdIn = new HashSet<>();
        Set<String> userIdIn = new HashSet<>();
        Map<Long, String> userNameMapStr = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entityExt : list) {
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            customerIdIn.add(data.getLongValue(QuotationEnum.CUSTOMER_ID.getAttr()));
            userNameMapStr.put(entityExt.getDataId(), data.getString(QuotationEnum.QUOTATION_PERSON.getAttr())+ StringConstant.LEAVE_ANOTHER_MARK);
            userIdIn.add(data.getString(QuotationEnum.QUOTATION_PERSON.getAttr()));
        }
        //客户id-名称map
        CustomerManagementEnum customerNameEnum = CustomerManagementEnum.NAME;
        List<String> fieldList = Arrays.asList("id", "dataId", CustomerManagementEnum.getAttrConnectData(customerNameEnum));
        Map<Long, String> customerIdNameMap = formHelp.getFormIdAttrMapByIds4All(customerNameEnum.getAttr(), corpid, indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode()), customerIdIn, fieldList);
        //员工id--员工名称
        Map<String, String> userNameMap = commonHelp.getUserNameMapByIds(corpid, userIdIn);
        //最终结果
        List<AppListPojo> appListPojos = new ArrayList<>();
        for (PaasFormDataEntityExt entityExt : list) {
            Long quotationId = entityExt.getId();
            JSONObject data = JsonHelperUtil.getJSONObject(entityExt.getData());
            String number = entityExt.getSerialNo();
            String name = String.valueOf(data.getOrDefault(QuotationEnum.NAME.getAttr(), ""));
            Long customerId = data.getLong(QuotationEnum.CUSTOMER_ID.getAttr());
            String customerName = customerIdNameMap.getOrDefault(customerId, "");
            String quotationPerson = userNameMap.getOrDefault(data.getString(QuotationEnum.QUOTATION_PERSON.getAttr()), userNameMapStr.getOrDefault(quotationId, ""));
            String quotationTime = DateTimeUtil.getStringEpochSecond(data.getLong(QuotationEnum.QUOTATION_TIME.getAttr()), DateTimeUtil.SDFDate);
            Double amount = data.getDoubleValue(QuotationEnum.AMOUNT.getAttr());
            String amountStr = StringUtil.formatDouble(amount);
            //摘要
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            summaryList.add(commonHelp.setSummary(QuotationEnum.NAME.getAttrName(), name));
            summaryList.add(commonHelp.setSummary(QuotationEnum.CUSTOMER_ID.getAttrName(), customerName));
            summaryList.add(commonHelp.setSummary(QuotationEnum.QUOTATION_PERSON.getAttrName(), quotationPerson));
            summaryList.add(commonHelp.setSummary(QuotationEnum.QUOTATION_TIME.getAttrName(), quotationTime));
            JSONObject others = new JSONObject();
            others.put("amount", amountStr);
            List<FormTitlePoJo> titleList = new ArrayList<>();
            titleList.add(commonHelp.setTitle(number));
            Long appId = entityExt.getAppId();
            Long menuId = entityExt.getMenuId();
            Long formId = entityExt.getFormId();
            JSONObject superScript = new JSONObject();
            List<SummaryDataPoJo> lablesList = new ArrayList<>();
            appListPojos.add(new AppListPojo(quotationId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        ListAppVO listAppVo = new ListAppVO(appListPojos, resultThroughVo.getPageHelper().getRowsCount());
        resultThroughVo.setDataApp(listAppVo);
        return resultThroughVo;
    }

    /**
     * 处理回款单穿透页列表的others字段
     *
     * @param data 回款单数据
     * @return com.alibaba.fastjson.JSONObject
     * @author 徐俊杰
     * @date 2019/12/11 10:10
     * @since v1.0
     */
    private JSONObject disposePaymentSheetOthers(JSONObject data) {
        JSONObject others = new JSONObject();
        String typeCode = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
        String typeName = PaymentSheetTypeEnum.getByCode(typeCode).getName();
        Double amountDouble = FundHelp.getSheetAmount4PaymentSheet(data, typeCode);
        String amount = StringUtil.formatDouble(amountDouble);
        amount = amount + UnitEnum.MONEY.getName();
        others.put("amount", amount);
        others.put("status", typeName);
        //处理红冲和坏账状态
        boolean red = PaymentSheetTypeEnum.isRed(typeCode);
        int redStatus = red ? 1 : 0;
        boolean bad = PaymentSheetTypeEnum.isBad(typeCode);
        int badStatus = bad ? 1 : 0;
        others.put("isRed", redStatus);
        others.put("isBad", badStatus);
        return others;
    }

    /**
     * 处理付款单穿透页列表的others字段
     *
     * @param data 付款单单条数据
     * @return com.alibaba.fastjson.JSONObject
     * @throws XbbException
     * @author 徐俊杰
     * @date 2020/3/16 15:47
     * @since v1.0
     */
    private JSONObject disposePaySheetOthers(JSONObject data) throws XbbException {
        JSONObject others = new JSONObject();
        String typeCode = data.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
        String typeName = PaySheetTypeEnum.getByCode(typeCode).getName();
        Double amountDouble = FundHelp.getSheetAmount4PaySheet(data, typeCode);
        String amount = StringUtil.formatDouble(amountDouble);
        amount = amount + UnitEnum.MONEY.getName();
        others.put("amount", amount);
        others.put("status", typeName);
        //处理红冲和坏账状态
        boolean red = PaySheetTypeEnum.isRed(typeCode);
        int redStatus = red ? 1 : 0;
        boolean bad = PaySheetTypeEnum.isBad(typeCode);
        int badStatus = bad ? 1 : 0;
        others.put("isRed", redStatus);
        others.put("isBad", badStatus);
        return others;
    }

    /**
     * 获取回款单数据列表（UUID作为条件）
     *
     * @param corpid 公司id
     * @param uuidIn UUID集合
     * @return java.util.List<com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt>
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/12/16 9:22
     * @since v1.0
     */
    private List<PaasFormDataEntityExt> getPaymentSheetListByUUIds(String corpid, Collection<String> uuidIn) throws XbbException {
        String sheetUuid = FieldTypeEnum.SHEET_UUID.getAlias();
        PaymentSheetEnum paymentSheetContractEnum = PaymentSheetEnum.CONTRACT;
        PaymentSheetEnum paymentSheetTypeEnum = PaymentSheetEnum.PAYMENT_SHEET_TYPE;
        PaymentSheetEnum paymentSheetAmountEnum = PaymentSheetEnum.AMOUNT;
        PaymentSheetEnum paymentSheetWriteOffAmountEnum = PaymentSheetEnum.WRITE_OFF_AMOUNT;
        PaymentSheetEnum paymentSheetPaymentEnum = PaymentSheetEnum.PAYMENT;
        List<String> fieldList = Arrays.asList("id", "dataId", sheetUuid, PaymentSheetEnum.getAttrConnectData(paymentSheetContractEnum),
                PaymentSheetEnum.getAttrConnectData(paymentSheetAmountEnum), PaymentSheetEnum.getAttrConnectData(paymentSheetTypeEnum),
                PaymentSheetEnum.getAttrConnectData(paymentSheetWriteOffAmountEnum), PaymentSheetEnum.getAttrConnectData(paymentSheetPaymentEnum));
        BoolQueryBuilder boolQueryBuilder = chartQueryHelp.boolQueryBuilder4Base(corpid, 0);
        boolQueryBuilder.filter(termsQuery(sheetUuid + ".keyword", uuidIn));
        List<Integer> notParentCodeList = SheetAloneEnum.getNotParentCodeList();
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.SHEET_ALONE.getAlias(), notParentCodeList));
        return esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
    }

    /**
     * 获取合同的名称和编号拼凑出来的信息
     *
     * @param relatedMapList 当前id集合所对应的多个字段关系
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2020/2/19 14:43
     * @since v1.0
     */
    private String getNameNumberInfo(List<Map<String, String>> relatedMapList, String nameAttr, String numberAttr) {
        StringBuilder info = new StringBuilder();
        for (Map<String, String> map : relatedMapList) {
            String name = map.get(nameAttr);
            String serialNumber = map.get(numberAttr);
            if (info.length() != 0) {
                info.append(",");
            }
            boolean nameEmpty = StringUtil.isEmpty(name);
            boolean noNotEmpty = StringUtil.isNotEmpty(serialNumber);
            if (!nameEmpty && noNotEmpty) {
                info.append(name).append("(").append(serialNumber).append(")");
            }else if (nameEmpty && noNotEmpty) {
                info.append(serialNumber);
            }
        }
        return info.toString();
    }

    /**
     * 获取String类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @param defaultStr 要获取数据的默认值
     * @throws XbbException 类型转换失败异常
     * @author long.rao
     * @date 2020-06-04 13:34
     */
    private String getStringOrDefault(JSONObject data, String attr, String defaultStr) throws XbbException {
        String result = defaultStr;
        try {
            if (StringUtil.isNotEmpty(data.getString(attr))) {
                result = data.getString(attr);
            }
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
        return result;
    }

    /**
     * 获取阶段流失原因
     *
     * @param corpid 公司id
     * @param formId 表单id
     * @param wastageStr 字段code值
     * @throws
     * @return
     * @author hongxiao
     * @date 2021-06-28 15:08
     * @since
     * @version
     */
    private String getCustomerWastage(String corpid, Long formId, String wastageStr) {
        if (Objects.isNull(wastageStr)) {
            return "--";
        }
        // 获取客户阶段流失原因
        FormDataDictionaryEntity dbFormDataDictionary = formDataDictionaryModel.getByType(DictionaryEnum.CUSTOMER_STAGE_WASTAGE.getType(), corpid, formId);
        if (Objects.isNull(dbFormDataDictionary)) {
            return "--";
        }

        List<DictionaryPojo> dbList = JSONArray.parseArray(dbFormDataDictionary.getData(),DictionaryPojo.class);
        for (DictionaryPojo pojo : dbList) {
            if (Objects.equals(pojo.getValue(), wastageStr)) {
                return pojo.getText();
            }
        }
        return "--";
    }
}

